diff --git a/ChangeLog b/ChangeLog
index 67cf9513a4a..515a98f4180 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,52 @@
English Dolibarr ChangeLog
--------------------------------------------------------------
+***** ChangeLog for 11.0.5 compared to 11.0.4 *****
+FIX: $arraydefaultmessage is an object, as well as in /htdocs/core/class/html.formmail.class.php
+FIX: 10.0 - pagination in prelevement/bons.php
+FIX: 10.0 - undefined $langs if template file copy fails during activation of modContrat
+FIX: 11.0 - fatal with postgres on contact/agenda.php
+FIX: 11.0 - multicurrency amount not fetched when fetching payments from llx_paiement or llx_paiementfourn
+FIX: 11.0 - when using pdftk as per hidden conf USE_PDFTK_FOR_PDF_CONCAT, check that the file exists before displaying a success message
+FIX: #13841
+FIX: #13877 - Can validate invoice if there is a credit note with VAT 0% on an invoice with other lines with a VAT non 0%
+FIX: #13968
+FIX: #14001
+FIX: #14002
+FIX: 9.0 - delete unused mandatory argument from migrate_clean_association: argument count mismatch causes a fatal error since php7
+FIX: 9.0 - fatal during migration from 3.1 using PHP 7
+FIX: Accountancy - Binding index - Add a filter on sql request for module Subtotal & Jalon
+FIX: avoid error "Call to undefined function measuringUnitString()"
+FIX: BlindBoolean SQL injection reported by Christian Weiler
+FIX: Can create a credit note on situation invoice if previous is also
+FIX: can install module even if (x) was appended during download.
+FIX: copy value date of VariousPayment onto the new AccountLine
+FIX: count of open day when date and start are not open should be 0
+FIX: Default bank account was not loaded for document generation.
+FIX: Do not show stats panel if the user does not have permissions
+FIX: Fix link of the button to create a credit note and fix the awareness of a error that happen when wo create a credit note
+FIX: force rounding 2 on export ld compta
+FIX: free text on cash desk
+FIX: links into emails of notifications
+FIX: missing file manifest.json.php
+FIX: missing GetNomURL Hook in warehouse class
+FIX: missing hook init + table class + $page not set
+FIX: missing rollbacks on trigger bad return
+FIX: missing translation value for key "NoMorePredefinedProductToDispatch"
+FIX: percent must be displayed on one line
+FIX: php error if multicompany disabled
+FIX: Privilege escalation reported by wizlynx WLX-2020-011
+FIX: replace filter parameter "none" by "restricthtml"
+FIX: Rounding Total TVA in "crabe" model pdf
+FIX: Show ref_customer, amount on contract link object
+FIX: Site ec.europa.eu has moved to https://
+FIX: Tickets mail models doesn't work
+FIX: vulnerability reported by wizlynx WLX-2020-012
+FIX: We must only rename current bank receipt
+FIX: when creating a VariousPayment, the value date is not copied onto the AccountLine that gets created at the same time, so the bank transaction's value date will be the payment date instead of the payment's value date
+FIX: wrong url param
+FIX: XSS using the renaming of .noexe files - reported by Nolan.
+
***** ChangeLog for 11.0.4 compared to 11.0.3 *****
FIX: #13749
FIX: #7594 Expense report multi pagebreak
diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php
index 8ecef4cde05..e7ec48944e1 100644
--- a/htdocs/accountancy/class/accountancyexport.class.php
+++ b/htdocs/accountancy/class/accountancyexport.class.php
@@ -985,7 +985,7 @@ class AccountancyExport
print $racine_subledger_account . $separator; // deprecated CPTG & CPTA use instead
// MONT
- print price(abs($line->montant), 0, '', 1, 2).$separator;
+ print price(abs($line->montant), 0, '', 1, 2, 2).$separator;
// CODC
print $line->sens.$separator;
// CPTG
diff --git a/htdocs/accountancy/customer/card.php b/htdocs/accountancy/customer/card.php
index 0a39fbc8254..591606a7e26 100644
--- a/htdocs/accountancy/customer/card.php
+++ b/htdocs/accountancy/customer/card.php
@@ -34,8 +34,8 @@ $action = GETPOST('action', 'alpha');
$cancel = GETPOST('cancel', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
-$codeventil = GETPOST('codeventil');
-$id = GETPOST('id');
+$codeventil = GETPOST('codeventil', 'int');
+$id = GETPOST('id', 'int');
// Security check
if ($user->socid > 0)
diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php
index 48df5ce374a..26c97d0c04b 100644
--- a/htdocs/accountancy/customer/index.php
+++ b/htdocs/accountancy/customer/index.php
@@ -251,6 +251,7 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON aa.rowid = fd
$sql .= " WHERE f.datef >= '".$db->idate($search_date_start)."'";
$sql .= " AND f.datef <= '".$db->idate($search_date_end)."'";
$sql .= " AND f.fk_statut > 0";
+$sql .= " AND fd.product_type <= 2";
$sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy
$sql .= " AND aa.account_number IS NULL";
if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
@@ -327,10 +328,11 @@ $sql .= " WHERE f.datef >= '".$db->idate($search_date_start)."'";
$sql .= " AND f.datef <= '".$db->idate($search_date_end)."'";
$sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy
$sql .= " AND f.fk_statut > 0";
+$sql .= " AND fd.product_type <= 2";
if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
- $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_SITUATION.")";
+ $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.", ".Facture::TYPE_REPLACEMENT.", ".Facture::TYPE_CREDIT_NOTE.", ".Facture::TYPE_SITUATION.")";
} else {
- $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_DEPOSIT.",".Facture::TYPE_SITUATION.")";
+ $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.", ".Facture::TYPE_REPLACEMENT.", ".Facture::TYPE_CREDIT_NOTE.", ".Facture::TYPE_DEPOSIT.", ".Facture::TYPE_SITUATION.")";
}
$sql .= " AND aa.account_number IS NOT NULL";
$sql .= " GROUP BY fd.fk_code_ventilation,aa.account_number,aa.label";
@@ -403,10 +405,11 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
$sql .= " AND f.datef <= '".$db->idate($search_date_end)."'";
$sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy
$sql .= " AND f.fk_statut > 0";
+ $sql .= " AND fd.product_type <= 2";
if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
- $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_SITUATION.")";
+ $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.", ".Facture::TYPE_REPLACEMENT.", ".Facture::TYPE_CREDIT_NOTE.", ".Facture::TYPE_SITUATION.")";
} else {
- $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_DEPOSIT.",".Facture::TYPE_SITUATION.")";
+ $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.", ".Facture::TYPE_REPLACEMENT.", ".Facture::TYPE_CREDIT_NOTE.", ".Facture::TYPE_DEPOSIT.", ".Facture::TYPE_SITUATION.")";
}
dol_syslog('htdocs/accountancy/customer/index.php');
@@ -455,10 +458,11 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
$sql .= " AND f.datef <= '".$db->idate($search_date_end)."'";
$sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy
$sql .= " AND f.fk_statut > 0";
+ $sql .= " AND fd.product_type <= 2";
if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
- $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_SITUATION.")";
+ $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.", ".Facture::TYPE_REPLACEMENT.", ".Facture::TYPE_CREDIT_NOTE.", ".Facture::TYPE_SITUATION.")";
} else {
- $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_DEPOSIT.",".Facture::TYPE_SITUATION.")";
+ $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.", ".Facture::TYPE_REPLACEMENT.", ".Facture::TYPE_CREDIT_NOTE.", ".Facture::TYPE_DEPOSIT.", ".Facture::TYPE_SITUATION.")";
}
dol_syslog('htdocs/accountancy/customer/index.php');
diff --git a/htdocs/accountancy/expensereport/card.php b/htdocs/accountancy/expensereport/card.php
index 36d587e0c99..9d7c504354f 100644
--- a/htdocs/accountancy/expensereport/card.php
+++ b/htdocs/accountancy/expensereport/card.php
@@ -38,8 +38,8 @@ $action = GETPOST('action', 'alpha');
$cancel = GETPOST('cancel', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
-$codeventil = GETPOST('codeventil');
-$id = GETPOST('id');
+$codeventil = GETPOST('codeventil', 'int');
+$id = GETPOST('id', 'int');
// Security check
if ($user->socid > 0)
diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
index d849496d965..699bbf1eebc 100644
--- a/htdocs/accountancy/journal/bankjournal.php
+++ b/htdocs/accountancy/journal/bankjournal.php
@@ -254,7 +254,9 @@ if ($result) {
} else {
$tabpay[$obj->rowid]["lib"] = dol_trunc($obj->label, 60);
}
- $links = $object->get_url($obj->rowid); // Get an array('url'=>, 'url_id'=>, 'label'=>, 'type'=> 'fk_bank'=> )
+
+ // Load of url links to the line into llx_bank
+ $links = $object->get_url($obj->rowid); // Get an array('url'=>, 'url_id'=>, 'label'=>, 'type'=> 'fk_bank'=> )
//var_dump($i);
//var_dump($tabpay);
@@ -319,7 +321,8 @@ if ($result) {
$chargestatic->id = $links[$key]['url_id'];
$chargestatic->ref = $links[$key]['url_id'];
- $tabpay[$obj->rowid]["lib"] .= ' ' . $chargestatic->getNomUrl(2);
+ $tabpay[$obj->rowid]["lib"] .= ' '.$chargestatic->getNomUrl(2);
+ $reg = array();
if (preg_match('/^\((.*)\)$/i', $links[$key]['label'], $reg)) {
if ($reg[1] == 'socialcontribution')
$reg[1] = 'SocialContribution';
@@ -331,12 +334,14 @@ if ($result) {
$tabpay[$obj->rowid]["soclib"] = $chargestatic->getNomUrl(1, 30);
$tabpay[$obj->rowid]["paymentscid"] = $chargestatic->id;
+ // Retreive the accounting code of the social contribution of the payment from link of payment.
+ // Note: We have the social contribution id, it can be faster to get accounting code from social contribution id.
$sqlmid = 'SELECT cchgsoc.accountancy_code';
- $sqlmid .= " FROM " . MAIN_DB_PREFIX . "c_chargesociales cchgsoc ";
- $sqlmid .= " INNER JOIN " . MAIN_DB_PREFIX . "chargesociales as chgsoc ON chgsoc.fk_type=cchgsoc.id";
- $sqlmid .= " INNER JOIN " . MAIN_DB_PREFIX . "paiementcharge as paycharg ON paycharg.fk_charge=chgsoc.rowid";
- $sqlmid .= " INNER JOIN " . MAIN_DB_PREFIX . "bank_url as bkurl ON bkurl.url_id=paycharg.rowid";
- $sqlmid .= " WHERE bkurl.fk_bank=" . $obj->rowid;
+ $sqlmid .= " FROM ".MAIN_DB_PREFIX."c_chargesociales cchgsoc";
+ $sqlmid .= " INNER JOIN ".MAIN_DB_PREFIX."chargesociales as chgsoc ON chgsoc.fk_type=cchgsoc.id";
+ $sqlmid .= " INNER JOIN ".MAIN_DB_PREFIX."paiementcharge as paycharg ON paycharg.fk_charge=chgsoc.rowid";
+ $sqlmid .= " INNER JOIN ".MAIN_DB_PREFIX."bank_url as bkurl ON bkurl.url_id=paycharg.rowid AND bkurl.type = 'payment_sc'";
+ $sqlmid .= " WHERE bkurl.fk_bank=".$obj->rowid;
dol_syslog("accountancy/journal/bankjournal.php:: sqlmid=" . $sqlmid, LOG_DEBUG);
$resultmid = $db->query($sqlmid);
diff --git a/htdocs/accountancy/supplier/card.php b/htdocs/accountancy/supplier/card.php
index 6140f90fe8d..699459ad63a 100644
--- a/htdocs/accountancy/supplier/card.php
+++ b/htdocs/accountancy/supplier/card.php
@@ -38,8 +38,8 @@ $action = GETPOST('action', 'alpha');
$cancel = GETPOST('cancel', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
-$codeventil = GETPOST('codeventil');
-$id = GETPOST('id');
+$codeventil = GETPOST('codeventil', 'int');
+$id = GETPOST('id', 'int');
// Security check
if ($user->socid > 0)
diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php
index 3bc44698029..a4de51cec66 100644
--- a/htdocs/accountancy/supplier/index.php
+++ b/htdocs/accountancy/supplier/index.php
@@ -249,6 +249,7 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON aa.rowid = ff
$sql .= " WHERE ff.datef >= '".$db->idate($search_date_start)."'";
$sql .= " AND ff.datef <= '".$db->idate($search_date_end)."'";
$sql .= " AND ff.fk_statut > 0";
+$sql .= " AND ffd.product_type <= 2";
$sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
$sql .= " AND aa.account_number IS NULL";
$sql .= " GROUP BY ffd.fk_code_ventilation,aa.account_number,aa.label";
@@ -319,6 +320,7 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON aa.rowid = ff
$sql .= " WHERE ff.datef >= '".$db->idate($search_date_start)."'";
$sql .= " AND ff.datef <= '".$db->idate($search_date_end)."'";
$sql .= " AND ff.fk_statut > 0";
+$sql .= " AND ffd.product_type <= 2";
$sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
$sql .= " AND aa.account_number IS NOT NULL";
$sql .= " GROUP BY ffd.fk_code_ventilation,aa.account_number,aa.label";
@@ -389,6 +391,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
$sql .= " WHERE ff.datef >= '".$db->idate($search_date_start)."'";
$sql .= " AND ff.datef <= '".$db->idate($search_date_end)."'";
$sql .= " AND ff.fk_statut > 0";
+ $sql .= " AND ffd.product_type <= 2";
$sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
dol_syslog('htdocs/accountancy/supplier/index.php');
diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php
index 7d24b330d3e..21bcc17bd42 100644
--- a/htdocs/adherents/card.php
+++ b/htdocs/adherents/card.php
@@ -243,18 +243,16 @@ if (empty($reshook))
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
$birthdate = '';
- if (isset($_POST["birthday"]) && $_POST["birthday"]
- && isset($_POST["birthmonth"]) && $_POST["birthmonth"]
- && isset($_POST["birthyear"]) && $_POST["birthyear"])
+ if (GETPOST("birthday", 'int') && GETPOST("birthmonth", 'int') && GETPOST("birthyear", 'int'))
{
- $birthdate = dol_mktime(12, 0, 0, $_POST["birthmonth"], $_POST["birthday"], $_POST["birthyear"]);
+ $birthdate = dol_mktime(12, 0, 0, GETPOST("birthmonth", 'int'), GETPOST("birthday", 'int'), GETPOST("birthyear", 'int'));
}
- $lastname = $_POST["lastname"];
- $firstname = $_POST["firstname"];
- $gender = $_POST["gender"];
- $societe = $_POST["societe"];
- $morphy = $_POST["morphy"];
- $login = $_POST["login"];
+ $lastname = GETPOST("lastname", 'alphanohtml');
+ $firstname = GETPOST("firstname", 'alphanohtml');
+ $gender = GETPOST("gender", 'alphanohtml');
+ $societe = GETPOST("societe", 'alphanohtml');
+ $morphy = GETPOST("morphy", 'alphanohtml');
+ $login = GETPOST("login", 'alphanohtml');
if ($morphy != 'mor' && empty($lastname)) {
$error++;
$langs->load("errors");
@@ -284,19 +282,19 @@ if (empty($reshook))
$object->oldcopy = clone $object;
// Change values
- $object->civility_id = trim(GETPOST("civility_id", 'alpha'));
- $object->firstname = trim(GETPOST("firstname", 'alpha'));
- $object->lastname = trim(GETPOST("lastname", 'alpha'));
- $object->gender = trim(GETPOST("gender", 'alpha'));
+ $object->civility_id = trim(GETPOST("civility_id", 'alphanohtml'));
+ $object->firstname = trim(GETPOST("firstname", 'alphanohtml'));
+ $object->lastname = trim(GETPOST("lastname", 'alphanohtml'));
+ $object->gender = trim(GETPOST("gender", 'alphanohtml'));
$object->login = trim(GETPOST("login", 'alpha'));
$object->pass = trim(GETPOST("pass", 'alpha'));
- $object->societe = trim(GETPOST("societe", 'alpha')); // deprecated
- $object->company = trim(GETPOST("societe", 'alpha'));
+ $object->societe = trim(GETPOST("societe", 'alphanohtml')); // deprecated
+ $object->company = trim(GETPOST("societe", 'alphanohtml'));
- $object->address = trim(GETPOST("address", 'alpha'));
- $object->zip = trim(GETPOST("zipcode", 'alpha'));
- $object->town = trim(GETPOST("town", 'alpha'));
+ $object->address = trim(GETPOST("address", 'alphanohtml'));
+ $object->zip = trim(GETPOST("zipcode", 'alphanohtml'));
+ $object->town = trim(GETPOST("town", 'alphanohtml'));
$object->state_id = GETPOST("state_id", 'int');
$object->country_id = GETPOST("country_id", 'int');
@@ -442,14 +440,14 @@ if (empty($reshook))
}
$typeid = GETPOST("typeid", 'int');
- $civility_id = GETPOST("civility_id", 'alpha');
- $lastname = GETPOST("lastname", 'alpha');
- $firstname = GETPOST("firstname", 'alpha');
- $gender = GETPOST("gender", 'alpha');
- $societe = GETPOST("societe", 'alpha');
- $address = GETPOST("address", 'alpha');
- $zip = GETPOST("zipcode", 'alpha');
- $town = GETPOST("town", 'alpha');
+ $civility_id = GETPOST("civility_id", 'alphanohtml');
+ $lastname = GETPOST("lastname", 'alphanohtml');
+ $firstname = GETPOST("firstname", 'alphanohtml');
+ $gender = GETPOST("gender", 'alphanohtml');
+ $societe = GETPOST("societe", 'alphanohtml');
+ $address = GETPOST("address", 'alphanohtml');
+ $zip = GETPOST("zipcode", 'alphanohtml');
+ $town = GETPOST("town", 'alphanohtml');
$state_id = GETPOST("state_id", 'int');
$country_id = GETPOST("country_id", 'int');
@@ -465,9 +463,8 @@ if (empty($reshook))
$pass = GETPOST("password", 'alpha');
$photo = GETPOST("photo", 'alpha');
//$comment=GETPOST("comment",'none');
- $morphy = GETPOST("morphy", 'alpha');
- $subscription = GETPOST("subscription", 'alpha');
- $public = GETPOST("public", 'alpha');
+ $morphy = GETPOST("morphy", 'alphanohtml');
+ $public = GETPOST("public", 'alphanohtml');
$userid = GETPOST("userid", 'int');
$socid = GETPOST("socid", 'int');
@@ -976,7 +973,7 @@ else
print "\n";
// Company
- print '
'.$langs->trans("Company").' ';
+ print ''.$langs->trans("Company").' ';
// Civility
print ''.$langs->trans("UserTitle").' ';
@@ -984,39 +981,39 @@ else
print ' ';
// Lastname
- print ''.$langs->trans("Lastname").' ';
+ print ''.$langs->trans("Lastname").' ';
print ' ';
// Firstname
- print ''.$langs->trans("Firstname").' ';
+ print ''.$langs->trans("Firstname").' ';
print ' ';
// Gender
print ''.$langs->trans("Gender").' ';
print '';
$arraygender = array('man'=>$langs->trans("Genderman"), 'woman'=>$langs->trans("Genderwoman"));
- print $form->selectarray('gender', $arraygender, GETPOST('gender'), 1);
+ print $form->selectarray('gender', $arraygender, GETPOST('gender', 'alphanohtml'), 1);
print ' ';
// EMail
- print ''.img_picto('', 'object_email').' '.($conf->global->ADHERENT_MAIL_REQUIRED ? '' : '').$langs->trans("EMail").($conf->global->ADHERENT_MAIL_REQUIRED ? ' ' : '').' ';
+ print ''.img_picto('', 'object_email').' '.($conf->global->ADHERENT_MAIL_REQUIRED ? '' : '').$langs->trans("EMail").($conf->global->ADHERENT_MAIL_REQUIRED ? ' ' : '').' ';
// Address
print ''.$langs->trans("Address").' ';
- print '';
+ print '';
print ' ';
// Zip / Town
print ''.$langs->trans("Zip").' / '.$langs->trans("Town").' ';
- print $formcompany->select_ziptown((GETPOST('zipcode', 'alphanohtml') ?GETPOST('zipcode', 'alphanohtml') : $object->zip), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6);
+ print $formcompany->select_ziptown((GETPOSTISSET('zipcode') ? GETPOST('zipcode', 'alphanohtml') : $object->zip), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6);
print ' ';
- print $formcompany->select_ziptown((GETPOST('town', 'alphanohtml') ?GETPOST('town', 'alphanohtml') : $object->town), 'town', array('zipcode', 'selectcountry_id', 'state_id'));
+ print $formcompany->select_ziptown((GETPOSTISSET('town') ? GETPOST('town', 'alphanohtml') : $object->town), 'town', array('zipcode', 'selectcountry_id', 'state_id'));
print ' ';
// Country
$object->country_id = $object->country_id ? $object->country_id : $mysoc->country_id;
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(GETPOSTISSET('country_id') ? GETPOST('country_id', 'alpha') : $object->country_id, 'country_id');
if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
print ' ';
@@ -1026,7 +1023,7 @@ else
print ''.$langs->trans('State').' ';
if ($object->country_id)
{
- print $formcompany->select_state(GETPOST('state_id', 'int') ?GETPOST('state_id', 'int') : $object->state_id, $object->country_code);
+ print $formcompany->select_state(GETPOSTISSET('state_id') ? GETPOST('state_id', 'int') : $object->state_id, $object->country_code);
}
else
{
@@ -1036,18 +1033,18 @@ else
}
// Pro phone
- print ' '.img_picto('', 'object_phoning').' '.$langs->trans("PhonePro").' ';
+ print ''.img_picto('', 'object_phoning').' '.$langs->trans("PhonePro").' ';
// Personal phone
- print ''.img_picto('', 'object_phoning').' '.$langs->trans("PhonePerso").' ';
+ print ''.img_picto('', 'object_phoning').' '.$langs->trans("PhonePerso").' ';
// Mobile phone
- print ''.img_picto('', 'object_phoning_mobile').' '.$langs->trans("PhoneMobile").' ';
+ print ''.img_picto('', 'object_phoning_mobile').' '.$langs->trans("PhoneMobile").' ';
if (!empty($conf->socialnetworks->enabled)) {
foreach ($socialnetworks as $key => $value) {
if (!$value['active']) break;
- print ''.$langs->trans($value['label']).' ';
+ print ''.$langs->trans($value['label']).' ';
}
}
@@ -1196,14 +1193,14 @@ else
$morphys["phy"] = $langs->trans("Physical");
$morphys["mor"] = $langs->trans("Moral");
print ''.$langs->trans("MemberNature").' ';
- print $form->selectarray("morphy", $morphys, (GETPOSTISSET("morphy") ?GETPOST("morphy", 'alpha') : $object->morphy));
+ print $form->selectarray("morphy", $morphys, (GETPOSTISSET("morphy") ? GETPOST("morphy", 'alpha') : $object->morphy));
print " ";
// Type
print ''.$langs->trans("Type").' ';
if ($user->rights->adherent->creer)
{
- print $form->selectarray("typeid", $adht->liste_array(), (GETPOSTISSET("typeid") ?GETPOST("typeid", 'int') : $object->typeid));
+ print $form->selectarray("typeid", $adht->liste_array(), (GETPOSTISSET("typeid") ? GETPOST("typeid", 'int') : $object->typeid));
}
else
{
@@ -1213,27 +1210,27 @@ else
print " ";
// Company
- print ''.$langs->trans("Company").' company).'"> ';
+ print ''.$langs->trans("Company").' company).'"> ';
// Civility
print ''.$langs->trans("UserTitle").' ';
- print $formcompany->select_civility(isset($_POST["civility_id"]) ? $_POST["civility_id"] : $object->civility_id)."\n";
+ print $formcompany->select_civility(GETPOSTISSET("civility_id") ? GETPOST("civility_id", 'alpha') : $object->civility_id)."\n";
print ' ';
print ' ';
// Lastname
- print ''.$langs->trans("Lastname").' lastname).'"> ';
+ print ''.$langs->trans("Lastname").' lastname).'"> ';
print ' ';
// Firstname
- print ''.$langs->trans("Firstname").' firstname).'"> ';
+ print ''.$langs->trans("Firstname").' firstname).'"> ';
print ' ';
// Gender
print ''.$langs->trans("Gender").' ';
print '';
$arraygender = array('man'=>$langs->trans("Genderman"), 'woman'=>$langs->trans("Genderwoman"));
- print $form->selectarray('gender', $arraygender, GETPOST('gender') ?GETPOST('gender') : $object->gender, 1);
+ print $form->selectarray('gender', $arraygender, GETPOSTISSET('gender') ? GETPOST('gender', 'alphanohtml') : $object->gender, 1);
print ' ';
// Photo
@@ -1256,14 +1253,14 @@ else
// Address
print ''.$langs->trans("Address").' ';
- print '';
+ print '';
print ' ';
// Zip / Town
print ''.$langs->trans("Zip").' / '.$langs->trans("Town").' ';
- print $formcompany->select_ziptown((isset($_POST["zipcode"]) ?GETPOST("zipcode", '', 2) : $object->zip), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6);
+ print $formcompany->select_ziptown((GETPOSTISSET("zipcode") ? GETPOST("zipcode", 'alphanohtml', 2) : $object->zip), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6);
print ' ';
- print $formcompany->select_ziptown((isset($_POST["town"]) ?GETPOST("town", '', 2) : $object->town), 'town', array('zipcode', 'selectcountry_id', 'state_id'));
+ print $formcompany->select_ziptown((GETPOSTISSET("town") ? GETPOST("town", 'alphanohtml', 2) : $object->town), 'town', array('zipcode', 'selectcountry_id', 'state_id'));
print ' ';
// Country
@@ -1282,18 +1279,18 @@ else
}
// Pro phone
- print ''.img_picto('', 'object_phoning').' '.$langs->trans("PhonePro").' phone).'"> ';
+ print ''.img_picto('', 'object_phoning').' '.$langs->trans("PhonePro").' phone).'"> ';
// Personal phone
- print ''.img_picto('', 'object_phoning').' '.$langs->trans("PhonePerso").' phone_perso).'"> ';
+ print ''.img_picto('', 'object_phoning').' '.$langs->trans("PhonePerso").' phone_perso).'"> ';
// Mobile phone
- print ''.img_picto('', 'object_phoning_mobile').' '.$langs->trans("PhoneMobile").' phone_mobile).'"> ';
+ print ''.img_picto('', 'object_phoning_mobile').' '.$langs->trans("PhoneMobile").' phone_mobile).'"> ';
if (!empty($conf->socialnetworks->enabled)) {
foreach ($socialnetworks as $key => $value) {
if (!$value['active']) break;
- print ''.$langs->trans($value['label']).' ';
+ print ''.$langs->trans($value['label']).' ';
}
}
@@ -1304,7 +1301,7 @@ else
// Public profil
print "".$langs->trans("Public")." \n";
- print $form->selectyesno("public", (isset($_POST["public"]) ?GETPOST("public", '', 2) : $object->public), 1);
+ print $form->selectyesno("public", (GETPOSTISSET("public") ? GETPOST("public", 'alphanohtml', 2) : $object->public), 1);
print " \n";
// Categories
diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php
index 04c5baa642a..eeede7b3810 100644
--- a/htdocs/adherents/class/adherent.class.php
+++ b/htdocs/adherents/class/adherent.class.php
@@ -2282,7 +2282,7 @@ class Adherent extends CommonObject
$sql.= " WHERE a.fk_adherent_type = t.rowid";
$sql.= " AND a.statut = 1";
$sql.= " AND a.entity IN (".getEntity('adherent').")";
- $sql.= " AND ((a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."') AND t.subscription = 1)";
+ $sql.= " AND ((a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."') AND t.subscription = '1')";
$resql=$this->db->query($sql);
if ($resql)
diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php
index 3aa5927af63..60a15f4899e 100644
--- a/htdocs/admin/mails_templates.php
+++ b/htdocs/admin/mails_templates.php
@@ -168,6 +168,7 @@ if ($conf->societe->enabled) $elementList['thirdparty'] = $langs->tran
if ($conf->adherent->enabled) $elementList['member'] = $langs->trans('MailToMember');
if ($conf->contrat->enabled) $elementList['contract'] = $langs->trans('MailToSendContract');
if ($conf->projet->enabled) $elementList['project'] = $langs->trans('MailToProject');
+if ($conf->ticket->enabled) $elementList['ticket_send'] = $langs->trans('MailToTicket');
$elementList['user'] = $langs->trans('MailToUser');
$parameters = array('elementList'=>$elementList);
diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php
index 72eb8240c10..b11808a2365 100644
--- a/htdocs/admin/modules.php
+++ b/htdocs/admin/modules.php
@@ -118,6 +118,7 @@ if ($action == 'install')
// $original_file should match format module_modulename-x.y[.z].zip
$original_file = basename($_FILES["fileinstall"]["name"]);
+ $original_file = preg_replace('/\(\d+\)\.zip$/i', '.zip', $original_file);
$newfile = $conf->admin->dir_temp.'/'.$original_file.'/'.$original_file;
if (!$original_file)
diff --git a/htdocs/comm/mailing/info.php b/htdocs/comm/mailing/info.php
index 3dfe0c4264c..070d46f6104 100644
--- a/htdocs/comm/mailing/info.php
+++ b/htdocs/comm/mailing/info.php
@@ -27,7 +27,7 @@ require_once DOL_DOCUMENT_ROOT.'/comm/mailing/class/mailing.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/emailing.lib.php';
-$id = GETPOST('id');
+$id = GETPOST('id', 'int');
// Load translation files required by the page
$langs->load("mails");
diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
index 54506a4a816..e356a4d5936 100644
--- a/htdocs/commande/class/commande.class.php
+++ b/htdocs/commande/class/commande.class.php
@@ -1014,7 +1014,7 @@ class Commande extends CommonOrder
// Complete vat rate with code
$vatrate = $line->tva_tx;
if ($line->vat_src_code && !preg_match('/\(.*\)/', $vatrate)) $vatrate .= ' ('.$line->vat_src_code.')';
-
+ $origin = (!empty($line->origin) ? $line->origin : $this->element);
$result = $this->addline(
$line->desc,
$line->subprice,
@@ -1039,7 +1039,7 @@ class Commande extends CommonOrder
$line->label,
$line->array_options,
$line->fk_unit,
- $this->element,
+ $origin,
$line->id
);
if ($result < 0)
diff --git a/htdocs/compta/bank/class/paymentvarious.class.php b/htdocs/compta/bank/class/paymentvarious.class.php
index 58e01ec2f28..21e9dd02e01 100644
--- a/htdocs/compta/bank/class/paymentvarious.class.php
+++ b/htdocs/compta/bank/class/paymentvarious.class.php
@@ -422,7 +422,11 @@ class PaymentVarious extends CommonObject
$sign * abs($this->amount),
$this->num_payment,
($this->category_transaction > 0 ? $this->category_transaction : 0),
- $user
+ $user,
+ '',
+ '',
+ '',
+ $this->datev
);
// Update fk_bank into llx_paiement.
diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php
index a16927bda0b..5ef3fbf0953 100644
--- a/htdocs/compta/bank/releve.php
+++ b/htdocs/compta/bank/releve.php
@@ -179,7 +179,7 @@ $sqlrequestforbankline = $sql;
if ($action == 'confirm_editbankreceipt' && !empty($oldbankreceipt) && !empty($newbankreceipt))
{
// TODO Add a test to check newbankreceipt does not exists yet
- $sqlupdate = 'UPDATE '.MAIN_DB_PREFIX.'bank SET num_releve = "'.$db->escape($newbankreceipt).'" WHERE num_releve = "'.$db->escape($oldbankreceipt).'"';
+ $sqlupdate = 'UPDATE '.MAIN_DB_PREFIX.'bank SET num_releve = "'.$db->escape($newbankreceipt).'" WHERE num_releve = "'.$db->escape($oldbankreceipt).'" AND fk_account = '.$id;
$result = $db->query($sqlupdate);
if ($result < 0) dol_print_error($db);
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index c726e1d8fed..fd6dd0baad0 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -319,15 +319,23 @@ if (empty($reshook))
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) {
+ $langs->load("errors");
// Using negative lines on deposit lead to headach and blocking problems when you want to consume them.
setEventMessages($langs->trans("ErrorLinesCantBeNegativeOnDeposits"), null, 'errors');
+ $error++;
+ $action = '';
} else {
- setEventMessages($langs->trans("ErrorLinesCantBeNegativeForOneVATRate"), null, 'errors');
+ $tmpvatratetoshow = explode('_', $vatrate);
+ $tmpvatratetoshow[0] = round($tmpvatratetoshow[0], 2);
+
+ if ($tmpvatratetoshow[0] != 0) {
+ $langs->load("errors");
+ setEventMessages($langs->trans("ErrorLinesCantBeNegativeForOneVATRate", $tmpvatratetoshow[0]), null, 'errors');
+ $error++;
+ $action = '';
+ }
}
- $error++;
- $action = '';
}
}
}
@@ -1092,6 +1100,11 @@ if (empty($reshook))
}
$id = $object->create($user);
+ // NOTE: Pb with situation invoice
+ // NOTE: fields total on situation invoice are stored as cumulative values on total of lines (bad) but delta on invoice total
+ // NOTE: fields total on credit note are stored as delta both on total of lines and on invoice total (good)
+ // NOTE: fields situation_percent on situation invoice are stored as cumulative values on lines (bad)
+ // NOTE: fields situation_percent on credit note are stored as delta on lines (good)
if (GETPOST('invoiceAvoirWithLines', 'int') == 1 && $id > 0)
{
if (!empty($facture_source->lines))
@@ -1112,17 +1125,17 @@ if (empty($reshook))
}
-
-
if ($facture_source->type == Facture::TYPE_SITUATION)
{
$source_fk_prev_id = $line->fk_prev_id; // temporary storing situation invoice fk_prev_id
- $line->fk_prev_id = $line->id; // Credit note line need to be linked to the situation invoice it is create from
+ $line->fk_prev_id = $line->id; // The new line of the new credit note we are creating must be linked to the situation invoice line it is created from
if (!empty($facture_source->tab_previous_situation_invoice))
{
- // search the last invoice in cycle
- $lineIndex = count($facture_source->tab_previous_situation_invoice) - 1;
+ // search the last standard invoice in cycle and the possible credit note between this last and facture_source
+ // TODO Move this out of loop of $facture_source->lines
+ $tab_jumped_credit_notes = array();
+ $lineIndex = count($facture_source->tab_previous_situation_invoice) - 1;
$searchPreviousInvoice = true;
while ($searchPreviousInvoice)
{
@@ -1133,11 +1146,13 @@ if (empty($reshook))
}
else
{
+ if ($facture_source->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_CREDIT_NOTE) {
+ $tab_jumped_credit_notes[$lineIndex] = $facture_source->tab_previous_situation_invoice[$lineIndex]->id;
+ }
$lineIndex--; // go to previous invoice in cycle
}
}
-
$maxPrevSituationPercent = 0;
foreach ($facture_source->tab_previous_situation_invoice[$lineIndex]->lines as $prevLine)
{
@@ -1161,6 +1176,36 @@ if (empty($reshook))
// prorata
$line->situation_percent = $maxPrevSituationPercent - $line->situation_percent;
+
+ //print 'New line based on invoice id '.$facture_source->tab_previous_situation_invoice[$lineIndex]->id.' fk_prev_id='.$source_fk_prev_id.' will be fk_prev_id='.$line->fk_prev_id.' '.$line->total_ht.' '.$line->situation_percent.' ';
+
+ // If there is some credit note between last situation invoice and invoice used for credit note generation (note: credit notes are stored as delta)
+ $maxPrevSituationPercent = 0;
+ foreach ($tab_jumped_credit_notes as $index => $creditnoteid) {
+ foreach ($facture_source->tab_previous_situation_invoice[$index]->lines as $prevLine)
+ {
+ if ($prevLine->fk_prev_id == $source_fk_prev_id)
+ {
+ $maxPrevSituationPercent = $prevLine->situation_percent;
+
+ $line->total_ht -= $prevLine->total_ht;
+ $line->total_tva -= $prevLine->total_tva;
+ $line->total_ttc -= $prevLine->total_ttc;
+ $line->total_localtax1 -= $prevLine->total_localtax1;
+ $line->total_localtax2 -= $prevLine->total_localtax2;
+
+ $line->multicurrency_subprice -= $prevLine->multicurrency_subprice;
+ $line->multicurrency_total_ht -= $prevLine->multicurrency_total_ht;
+ $line->multicurrency_total_tva -= $prevLine->multicurrency_total_tva;
+ $line->multicurrency_total_ttc -= $prevLine->multicurrency_total_ttc;
+ }
+ }
+ }
+
+ // prorata
+ $line->situation_percent += $maxPrevSituationPercent;
+
+ //print 'New line based on invoice id '.$facture_source->tab_previous_situation_invoice[$lineIndex]->id.' fk_prev_id='.$source_fk_prev_id.' will be fk_prev_id='.$line->fk_prev_id.' '.$line->total_ht.' '.$line->situation_percent.' ';
}
}
@@ -1208,7 +1253,7 @@ if (empty($reshook))
}
// Add link between credit note and origin
- if (!empty($object->fk_facture_source)) {
+ if (!empty($object->fk_facture_source) && $id > 0) {
$facture_source->fetch($object->fk_facture_source);
$facture_source->fetchObjectLinked();
@@ -1397,7 +1442,7 @@ if (empty($reshook))
if ($_POST['type'] == Facture::TYPE_DEPOSIT)
{
$typeamount = GETPOST('typedeposit', 'alpha');
- $valuedeposit = GETPOST('valuedeposit', 'int');
+ $valuedeposit = price2num(GETPOST('valuedeposit', 'alpha'), 'MU');
$amountdeposit = array();
if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA))
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index 80a0e4273aa..d3c9ae19721 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -1740,7 +1740,8 @@ class Facture extends CommonInvoice
}
/**
- * Fetch previous and next situations invoices
+ * Fetch previous and next situations invoices.
+ * Return all previous and next invoices (both standard and credit notes).
*
* @return void
*/
@@ -1751,7 +1752,7 @@ class Facture extends CommonInvoice
$this->tab_previous_situation_invoice = array();
$this->tab_next_situation_invoice = array();
- $sql = 'SELECT rowid, situation_counter FROM '.MAIN_DB_PREFIX.'facture';
+ $sql = 'SELECT rowid, type, situation_cycle_ref, situation_counter FROM '.MAIN_DB_PREFIX.'facture';
$sql .= ' WHERE rowid <> '.$this->id;
$sql .= ' AND entity = '.$this->entity;
$sql .= ' AND situation_cycle_ref = '.(int) $this->situation_cycle_ref;
diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
index 71c8596e00a..05d2fe0c08b 100644
--- a/htdocs/compta/paiement/class/paiement.class.php
+++ b/htdocs/compta/paiement/class/paiement.class.php
@@ -68,9 +68,10 @@ 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 (in the main currency)
+ public $multicurrency_amount; // Total amount of payment (in the currency of the bank account)
+ public $amounts=array(); // array: invoice ID => amount for that invoice (in the main currency)>
+ public $multicurrency_amounts=array(); // array: invoice ID => amount for that invoice (in the invoice's currency)>
public $author;
public $paiementid; // Type of payment. Id saved into fields fk_paiement on llx_paiement
public $paiementcode; // Code of payment.
@@ -159,7 +160,7 @@ 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 = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.ext_payment_id, p.ext_payment_site, p.fk_bank, p.multicurrency_amount,';
$sql.= ' c.code as type_code, c.libelle as type_label,';
$sql.= ' p.num_paiement as num_payment, p.note,';
$sql.= ' b.fk_account';
@@ -179,20 +180,21 @@ class Paiement extends CommonObject
if ($this->db->num_rows($resql))
{
$obj = $this->db->fetch_object($resql);
- $this->id = $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_payment = $obj->num_payment;
- $this->montant = $obj->amount; // deprecated
- $this->amount = $obj->amount;
- $this->note = $obj->note;
- $this->type_label = $obj->type_label;
- $this->type_code = $obj->type_code;
- $this->statut = $obj->statut;
- $this->ext_payment_id = $obj->ext_payment_id;
- $this->ext_payment_site = $obj->ext_payment_site;
+ $this->id = $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_payment = $obj->num_payment;
+ $this->montant = $obj->amount; // deprecated
+ $this->amount = $obj->amount;
+ $this->multicurrency_amount = $obj->multicurrency_amount;
+ $this->note = $obj->note;
+ $this->type_label = $obj->type_label;
+ $this->type_code = $obj->type_code;
+ $this->statut = $obj->statut;
+ $this->ext_payment_id = $obj->ext_payment_id;
+ $this->ext_payment_site = $obj->ext_payment_site;
$this->bank_account = $obj->fk_account; // deprecated
$this->fk_account = $obj->fk_account;
@@ -530,7 +532,9 @@ 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
+ if ($result == 0) {
+ $accline->id = $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);
diff --git a/htdocs/compta/paiement/info.php b/htdocs/compta/paiement/info.php
index 3da6a95a1e8..00c3440b868 100644
--- a/htdocs/compta/paiement/info.php
+++ b/htdocs/compta/paiement/info.php
@@ -31,7 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
// Load translation files required by the page
$langs->loadLangs(array('bills', 'companies'));
-$id = GETPOST('id');
+$id = GETPOST('id', 'int');
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'alpha');
$confirm = GETPOST('confirm', 'alpha');
diff --git a/htdocs/compta/prelevement/bons.php b/htdocs/compta/prelevement/bons.php
index 88162263297..e4c11c0c60c 100644
--- a/htdocs/compta/prelevement/bons.php
+++ b/htdocs/compta/prelevement/bons.php
@@ -31,6 +31,8 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
// Load translation files required by the page
$langs->loadLangs(array('banks', 'categories', 'widthdrawals'));
+$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'contractlist'; // To manage different context of search
+
// Security check
$socid = GETPOST('socid', 'int');
if ($user->socid) $socid=$user->socid;
@@ -102,7 +104,9 @@ if ($result)
$num = $db->num_rows($result);
$i = 0;
- $urladd = "&statut=".$statut;
+ $param = '';
+ $param .= "&statut=".$statut;
+ if ($limit != $conf->liste_limit) $param .= '&limit=' . $limit;
$selectedfields = '';
@@ -123,7 +127,7 @@ if ($result)
print ' ';
print ' ';
- print_barre_liste($langs->trans("WithdrawalsReceipts"), $page, $_SERVER["PHP_SELF"], $urladd, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit);
+ print_barre_liste($langs->trans("WithdrawalsReceipts"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit);
$moreforfilter = '';
diff --git a/htdocs/compta/resultat/index.php b/htdocs/compta/resultat/index.php
index 128e43b335a..6cef240644f 100644
--- a/htdocs/compta/resultat/index.php
+++ b/htdocs/compta/resultat/index.php
@@ -499,7 +499,7 @@ elseif ($modecompta == "BOOKKEEPING")
}
/*
- * Charges sociales non deductibles
+ * Social contributions
*/
$subtotal_ht = 0;
@@ -512,7 +512,6 @@ if (!empty($conf->tax->enabled) && ($modecompta == 'CREANCES-DETTES' || $modecom
$sql .= " FROM ".MAIN_DB_PREFIX."c_chargesociales as c";
$sql .= ", ".MAIN_DB_PREFIX."chargesociales as cs";
$sql .= " WHERE cs.fk_type = c.id";
- $sql .= " AND c.deductible = 0";
if (!empty($date_start) && !empty($date_end))
$sql .= " AND cs.date_ech >= '".$db->idate($date_start)."' AND cs.date_ech <= '".$db->idate($date_end)."'";
}
@@ -524,7 +523,6 @@ if (!empty($conf->tax->enabled) && ($modecompta == 'CREANCES-DETTES' || $modecom
$sql .= ", ".MAIN_DB_PREFIX."paiementcharge as p";
$sql .= " WHERE p.fk_charge = cs.rowid";
$sql .= " AND cs.fk_type = c.id";
- $sql .= " AND c.deductible = 0";
if (!empty($date_start) && !empty($date_end))
$sql .= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'";
}
@@ -532,69 +530,7 @@ if (!empty($conf->tax->enabled) && ($modecompta == 'CREANCES-DETTES' || $modecom
$sql .= " AND cs.entity = ".$conf->entity;
$sql .= " GROUP BY c.libelle, dm";
- dol_syslog("get social contributions deductible=0 ", LOG_DEBUG);
- $result = $db->query($sql);
- if ($result) {
- $num = $db->num_rows($result);
- $i = 0;
- if ($num) {
- while ($i < $num) {
- $obj = $db->fetch_object($result);
-
- if (!isset($decaiss[$obj->dm])) $decaiss[$obj->dm] = 0;
- $decaiss[$obj->dm] += $obj->amount;
-
- if (!isset($decaiss_ttc[$obj->dm])) $decaiss_ttc[$obj->dm] = 0;
- $decaiss_ttc[$obj->dm] += $obj->amount;
-
- $i++;
- }
- }
- } else {
- dol_print_error($db);
- }
-}
-elseif ($modecompta == "BOOKKEEPING")
-{
- // Nothing from this table
-}
-
-
-/*
- * Charges sociales deductibles
- */
-
-$subtotal_ht = 0;
-$subtotal_ttc = 0;
-if (!empty($conf->tax->enabled) && ($modecompta == 'CREANCES-DETTES' || $modecompta == "RECETTES-DEPENSES"))
-{
- if ($modecompta == 'CREANCES-DETTES')
- {
- $sql = "SELECT c.libelle as nom, date_format(cs.date_ech,'%Y-%m') as dm, sum(cs.amount) as amount";
- $sql .= " FROM ".MAIN_DB_PREFIX."c_chargesociales as c";
- $sql .= ", ".MAIN_DB_PREFIX."chargesociales as cs";
- $sql .= " WHERE cs.fk_type = c.id";
- $sql .= " AND c.deductible = 1";
- if (!empty($date_start) && !empty($date_end))
- $sql .= " AND cs.date_ech >= '".$db->idate($date_start)."' AND cs.date_ech <= '".$db->idate($date_end)."'";
- }
- elseif ($modecompta == "RECETTES-DEPENSES")
- {
- $sql = "SELECT c.libelle as nom, date_format(p.datep,'%Y-%m') as dm, sum(p.amount) as amount";
- $sql .= " FROM ".MAIN_DB_PREFIX."c_chargesociales as c";
- $sql .= ", ".MAIN_DB_PREFIX."chargesociales as cs";
- $sql .= ", ".MAIN_DB_PREFIX."paiementcharge as p";
- $sql .= " WHERE p.fk_charge = cs.rowid";
- $sql .= " AND cs.fk_type = c.id";
- $sql .= " AND c.deductible = 1";
- if (!empty($date_start) && !empty($date_end))
- $sql .= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'";
- }
-
- $sql .= " AND cs.entity = ".$conf->entity;
- $sql .= " GROUP BY c.libelle, dm";
-
- dol_syslog("get social contributions paid deductible=1", LOG_DEBUG);
+ dol_syslog("get social contributions", LOG_DEBUG);
$result = $db->query($sql);
if ($result) {
$num = $db->num_rows($result);
@@ -734,7 +670,7 @@ elseif ($modecompta == 'BOOKKEEPING') {
/*
- * Donation get dunning paiement
+ * Donation get dunning payments
*/
if (!empty($conf->don->enabled) && ($modecompta == 'CREANCES-DETTES' || $modecompta == "RECETTES-DEPENSES"))
diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php
index e7fb6469869..f0f65071207 100644
--- a/htdocs/contact/card.php
+++ b/htdocs/contact/card.php
@@ -403,6 +403,7 @@ if (empty($reshook))
//$object->twitter = GETPOST("twitter", 'alpha');
//$object->facebook = GETPOST("facebook", 'alpha');
//$object->linkedin = GETPOST("linkedin", 'alpha');
+ $object->socialnetworks = array();
if (!empty($conf->socialnetworks->enabled)) {
foreach ($socialnetworks as $key => $value) {
if (GETPOSTISSET($key) && GETPOST($key, 'alphanohtml') != '') {
diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php
index 8a1b26e9d33..dadb41179ca 100644
--- a/htdocs/contact/class/contact.class.php
+++ b/htdocs/contact/class/contact.class.php
@@ -1067,9 +1067,6 @@ class Contact extends CommonObject
$error = 0;
- //$this->old_lastname = $obj->lastname;
- //$this->old_firstname = $obj->firstname;
-
$this->db->begin();
if (!$error)
@@ -1081,7 +1078,7 @@ class Contact extends CommonObject
$sql .= " WHERE ec.fk_socpeople=".$this->id;
$sql .= " AND ec.fk_c_type_contact=tc.rowid";
$sql .= " AND tc.source='external'";
- dol_syslog(get_class($this)."::delete", LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
{
@@ -1094,7 +1091,7 @@ class Contact extends CommonObject
$sqldel = "DELETE FROM ".MAIN_DB_PREFIX."element_contact";
$sqldel .= " WHERE rowid = ".$obj->rowid;
- dol_syslog(get_class($this)."::delete", LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$result = $this->db->query($sqldel);
if (!$result)
{
@@ -1116,7 +1113,7 @@ class Contact extends CommonObject
{
// Remove Roles
$sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_socpeople = ".$this->id;
- dol_syslog(get_class($this)."::delete", LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql)
{
@@ -1130,7 +1127,7 @@ class Contact extends CommonObject
{
// Remove category
$sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_contact WHERE fk_socpeople = ".$this->id;
- dol_syslog(get_class($this)."::delete", LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql)
{
@@ -1144,7 +1141,7 @@ class Contact extends CommonObject
{
$sql = "DELETE FROM ".MAIN_DB_PREFIX."socpeople";
$sql .= " WHERE rowid=".$this->id;
- dol_syslog(get_class($this)."::delete", LOG_DEBUG);
+ dol_syslog(__METHOD__, LOG_DEBUG);
$result = $this->db->query($sql);
if (!$result)
{
diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php
index 90c93f6177b..f0bd9ddce4e 100644
--- a/htdocs/core/actions_linkedfiles.inc.php
+++ b/htdocs/core/actions_linkedfiles.inc.php
@@ -209,8 +209,10 @@ elseif ($action == 'renamefile' && GETPOST('renamefilesave', 'alpha'))
if (empty($reshook))
{
- if (! file_exists($destpath))
- {
+ if (preg_match('/^\./', $filenameto)) {
+ $langs->load("errors"); // key must be loaded because we can't rely on loading during output, we need var substitution to be done now.
+ setEventMessages($langs->trans("ErrorFilenameCantStartWithDot", $filenameto), null, 'errors');
+ } elseif (! file_exists($destpath)) {
$result = dol_move($srcpath, $destpath);
if ($result)
{
diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index b86e7bd692c..dc5b02286eb 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -1030,14 +1030,18 @@ if (!$error && $massaction == "builddoc" && $permissiontoread && !GETPOST('butto
$input_files .= ' '.escapeshellarg($f);
}
- $cmd = 'pdftk '.escapeshellarg($input_files).' cat output '.escapeshellarg($file);
+ $cmd = 'pdftk ' . $input_files . ' cat output '.escapeshellarg($file);
exec($cmd);
- if (!empty($conf->global->MAIN_UMASK))
- @chmod($file, octdec($conf->global->MAIN_UMASK));
-
- $langs->load("exports");
- setEventMessages($langs->trans('FileSuccessfullyBuilt', $filename.'_'.dol_print_date($now, 'dayhourlog')), null, 'mesgs');
+ // check if pdftk is installed
+ if (file_exists($file)) {
+ if (!empty($conf->global->MAIN_UMASK))
+ @chmod($file, octdec($conf->global->MAIN_UMASK));
+ $langs->load("exports");
+ setEventMessages($langs->trans('FileSuccessfullyBuilt', $filename.'_'.dol_print_date($now, 'dayhourlog')), null, 'mesgs');
+ } else {
+ setEventMessages($langs->trans('ErrorPDFTkOutputFileNotFound'), null, 'errors');
+ }
}
else
{
diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php
index 56910b43e4a..4a8e097fd6d 100644
--- a/htdocs/core/class/commondocgenerator.class.php
+++ b/htdocs/core/class/commondocgenerator.class.php
@@ -212,8 +212,8 @@ abstract class CommonDocGenerator
'company_idprof6'=>$object->idprof6,
'company_note_public'=>$object->note_public,
'company_note_private'=>$object->note_private,
- 'company_default_bank_iban'=>$object->bank_account->iban,
- 'company_default_bank_bic'=>$object->bank_account->bic
+ 'company_default_bank_iban'=>(is_object($object->bank_account) ? $object->bank_account->iban : ''),
+ 'company_default_bank_bic'=>(is_object($object->bank_account) ? $object->bank_account->bic : '')
);
// Retrieve extrafields
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 10e04896314..e104b82642d 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -438,10 +438,14 @@ abstract class CommonObject
public $next_prev_filter;
-
+ /**
+ * @var array List of child tables. To know object to delete on cascade.
+ * if name like with @ClassNAme:FilePathClass;ParentFkFieldName' it will
+ * call method deleteByParentField(parentId,ParentFkFieldName) to fetch and delete child object
+ */
+ protected $childtablesoncascade = array();
// No constructor as it is an abstract class
-
/**
* Check an object id/ref exists
* If you don't need/want to instantiate object and just need to know if object exists, use this method instead of fetch
@@ -3045,7 +3049,12 @@ abstract class CommonObject
//print 'Line '.$i.' rowid='.$obj->rowid.' vat_rate='.$obj->vatrate.' total_ht='.$obj->total_ht.' total_tva='.$obj->total_tva.' total_ttc='.$obj->total_ttc.' total_ht_by_vats='.$total_ht_by_vats[$obj->vatrate].' total_tva_by_vats='.$total_tva_by_vats[$obj->vatrate].' (new calculation = '.$tmpvat.') total_ttc_by_vats='.$total_ttc_by_vats[$obj->vatrate].($diff?" => DIFF":"")." \n";
if ($diff)
{
- if (abs($diff) > 0.1) { dol_syslog('A rounding difference was detected into TOTAL but is too high to be corrected', LOG_WARNING); exit; }
+ if (abs($diff) > 0.1) {
+ $errmsg = 'A rounding difference was detected into TOTAL but is too high to be corrected. Some data in your line may be corrupted. Try to edit each line manually.';
+ dol_syslog($errmsg, LOG_WARNING);
+ dol_print_error('', $errmsg);
+ exit;
+ }
$sqlfix = "UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldtva." = ".($obj->total_tva - $diff).", total_ttc = ".($obj->total_ttc - $diff)." WHERE rowid = ".$obj->rowid;
dol_syslog('We found a difference of '.$diff.' for line rowid = '.$obj->rowid.". We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix);
$resqlfix = $this->db->query($sqlfix);
@@ -7888,18 +7897,43 @@ abstract class CommonObject
}
// Delete cascade first
- if (!empty($this->childtablesoncascade)) {
+ if (is_array($this->childtablesoncascade) && !empty($this->childtablesoncascade)) {
foreach ($this->childtablesoncascade as $table)
{
- $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$table.' WHERE '.$this->fk_element.' = '.$this->id;
- $resql = $this->db->query($sql);
- if (!$resql)
- {
- $this->error = $this->db->lasterror();
- $this->errors[] = $this->error;
- $this->db->rollback();
- return -1;
- }
+ $deleteFromObject = explode(':', $table);
+ if (count($deleteFromObject)>=2) {
+ $className = str_replace('@', '', $deleteFromObject[0]);
+ $filePath = $deleteFromObject[1];
+ $columnName = $deleteFromObject[2];
+ if (dol_include_once($filePath)) {
+ $childObject = new $className($this->db);
+ if (method_exists($childObject, 'deleteByParentField')) {
+ $result = $childObject->deleteByParentField($this->id, $columnName);
+ if ($result < 0) {
+ $error++;
+ $this->errors[] = $childObject->error;
+ break;
+ }
+ } else {
+ $error++;
+ $this->errors[] = "You defined a cascade delete on an object $childObject but there is no method deleteByParentField for it";
+ break;
+ }
+ } else {
+ $error++;
+ $this->errors[] = 'Cannot include child class file ' .$filePath;
+ break;
+ }
+ } else {
+ $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $table . ' WHERE ' . $this->fk_element . ' = ' . $this->id;
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $error++;
+ $this->error = $this->db->lasterror();
+ $this->errors[] = $this->error;
+ break;
+ }
+ }
}
}
@@ -7946,6 +7980,66 @@ abstract class CommonObject
}
}
+ /**
+ * Delete all child object from a parent ID
+ *
+ * @param int $parentId Parent Id
+ * @param string $parentField Name of Foreign key parent column
+ * @return int <0 if KO, >0 if OK
+ * @throws Exception
+ */
+ public function deleteByParentField($parentId = 0, $parentField = '')
+ {
+ global $user;
+
+ $error = 0;
+ $deleted = 0;
+
+ if (!empty($parentId) && !empty($parentField)) {
+ $this->db->begin();
+
+ $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . $this->table_element;
+ $sql .= ' WHERE '.$parentField.' = ' . (int) $parentId;
+
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $this->errors[] = $this->db->lasterror();
+ $error++;
+ } else {
+ while ($obj = $this->db->fetch_object($resql)) {
+ $result = $this->fetch($obj->rowid);
+ if ($result < 0) {
+ $error++;
+ $this->errors[] = $this->error;
+ } else {
+ if (get_class($this) == 'Contact') { // TODO special code because delete() for contact has not been standardized like other delete.
+ $result = $this->delete();
+ } else {
+ $result = $this->delete($user);
+ }
+ if ($result < 0) {
+ $error++;
+ $this->errors[] = $this->error;
+ } else {
+ $deleted++;
+ }
+ }
+ }
+ }
+
+ if (empty($error)) {
+ $this->db->commit();
+ return $deleted;
+ } else {
+ $this->error = implode(', ', $this->errors);
+ $this->db->rollback();
+ return $error * -1;
+ }
+ }
+
+ return $deleted;
+ }
+
/**
* Delete a line of object in database
*
diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
index ac388b1ef83..f938426d4ba 100644
--- a/htdocs/core/class/extrafields.class.php
+++ b/htdocs/core/class/extrafields.class.php
@@ -1686,8 +1686,13 @@ class ExtraFields
}
elseif ($type == 'select')
{
- if ($langfile && $param['options'][$value]) $value = $langs->trans($param['options'][$value]);
- else $value = $param['options'][$value];
+ $valstr = $param['options'][$value];
+ if (($pos = strpos($valstr, "|")) !== false)
+ {
+ $valstr = substr($valstr, 0, $pos);
+ }
+ if ($langfile && $valstr) $value = $langs->trans($valstr);
+ else $value = $valstr;
}
elseif ($type == 'sellist')
{
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 078cfb2b5f2..1e1bbdf58d2 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -2802,6 +2802,7 @@ class Form
if ($result)
{
require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php';
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
$num = $this->db->num_rows($result);
@@ -3711,7 +3712,8 @@ class Form
$sql = 'SELECT rowid, ref, situation_cycle_ref, situation_counter, situation_final, fk_soc';
$sql .= ' FROM '.MAIN_DB_PREFIX.'facture';
$sql .= ' WHERE entity IN ('.getEntity('invoice').')';
- $sql .= ' AND situation_counter>=1';
+ $sql .= ' AND situation_counter >= 1';
+ $sql .= ' AND type <> 2';
$sql .= ' ORDER by situation_cycle_ref, situation_counter desc';
$resql = $this->db->query($sql);
if ($resql && $this->db->num_rows($resql) > 0) {
@@ -6946,7 +6948,8 @@ class Form
'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande').')'),
'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('invoice').')'),
'invoice_template'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToTemplateInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.titre as ref, t.total as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_rec as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('invoice').')'),
- 'contrat'=>array('enabled'=>$conf->contrat->enabled, 'perms'=>1, 'label'=>'LinkToContract', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('contract').')'),
+ 'contrat'=>array('enabled'=>$conf->contrat->enabled, 'perms'=>1, 'label'=>'LinkToContract',
+ 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_customer as ref_client, t.ref_supplier, '' as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('contract').')'),
'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('intervention').')'),
'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled, 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('supplier_proposal').')'),
'order_supplier'=>array('enabled'=>$conf->supplier_order->enabled, 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$listofidcompanytoscan.') AND t.entity IN ('.getEntity('commande_fournisseur').')'),
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index ec9dff5f1a3..97a4bdf1948 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -1269,7 +1269,8 @@ class FormFile
}
else
{
- print dol_trunc($file['name'], 200);
+ $filenametoshow = preg_replace('/\.noexe$/', '', $file['name']);
+ print dol_trunc($filenametoshow, 200);
print '';
}
// Preview link
diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php
index b688d408284..1db68fe008b 100644
--- a/htdocs/core/class/html.formticket.class.php
+++ b/htdocs/core/class/html.formticket.class.php
@@ -987,10 +987,10 @@ class FormTicket
}
// MESSAGE
- $defaultmessage = "";
- if (is_array($arraydefaultmessage) && count($arraydefaultmessage) > 0 && $arraydefaultmessage->content) {
- $defaultmessage = $arraydefaultmessage->content;
- }
+ $defaultmessage="";
+ if (is_object($arraydefaultmessage) && $arraydefaultmessage->content) {
+ $defaultmessage = $arraydefaultmessage->content;
+ }
$defaultmessage = str_replace('\n', "\n", $defaultmessage);
// Deal with format differences between message and signature (text / HTML)
diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php
index df7647b330c..9c071a36f23 100644
--- a/htdocs/core/class/smtps.class.php
+++ b/htdocs/core/class/smtps.class.php
@@ -428,7 +428,7 @@ class SMTPs
$host=preg_replace('@ssl://@i', '', $host); // Remove prefix
$host=preg_replace('@tls://@i', '', $host); // Remove prefix
- if ($usetls) $host='tls://'.$host;
+ if ($usetls && ! empty($conf->global->MAIN_SMTPS_ADD_TLS_TO_HOST_FOR_HELO)) $host = 'tls://'.$host;
$hosth = $host;
@@ -568,6 +568,8 @@ class SMTPs
$host=preg_replace('@ssl://@i', '', $host); // Remove prefix
$host=preg_replace('@tls://@i', '', $host); // Remove prefix
+ if ($usetls && ! empty($conf->global->MAIN_SMTPS_ADD_TLS_TO_HOST_FOR_HELO)) $host = 'tls://'.$host;
+
$hosth = $host;
if (! empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO))
diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php
index 30a1b80c232..48ab350d60f 100644
--- a/htdocs/core/lib/company.lib.php
+++ b/htdocs/core/lib/company.lib.php
@@ -1448,7 +1448,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = '', $noprin
$langs->load("mails");
$sql2 = "SELECT m.rowid as id, m.titre as label, mc.date_envoi as dp, mc.date_envoi as dp2, '100' as percent, 'mailing' as type";
- $sql2 .= ", '' as fk_element, '' as elementtype, '' as contact_id";
+ $sql2 .= ", null as fk_element, '' as elementtype, null as contact_id";
$sql2 .= ", 'AC_EMAILING' as acode, '' as alabel, '' as apicto";
$sql2 .= ", u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname"; // User that valid action
if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql2 .= ", '' as lastname, '' as firstname";
@@ -1460,7 +1460,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = '', $noprin
$sql2 .= " WHERE mc.email = '".$db->escape($objcon->email)."'"; // Search is done on email.
$sql2 .= " AND mc.statut = 1";
$sql2 .= " AND u.rowid = m.fk_user_valid";
- $sql2 .= " AND mc.fk_mailing=m.rowid";
+ $sql2 .= " AND mc.fk_mailing = m.rowid";
}
if (!empty($sql) && !empty($sql2)) {
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index 41d7bf1b294..23b631bae53 100644
--- a/htdocs/core/lib/files.lib.php
+++ b/htdocs/core/lib/files.lib.php
@@ -324,11 +324,13 @@ function completeFileArrayWithDatabaseInfo(&$filearray, $relativedir)
// Complete filearray with properties found into $filearrayindatabase
foreach ($filearray as $key => $val)
{
+ $tmpfilename = preg_replace('/\.noexe$/', '', $filearray[$key]['name']);
+
$found = 0;
// Search if it exists into $filearrayindatabase
foreach ($filearrayindatabase as $key2 => $val2)
{
- if ($filearrayindatabase[$key2]['name'] == $filearray[$key]['name'])
+ if ($filearrayindatabase[$key2]['name'] == $tmpfilename)
{
$filearray[$key]['position_name'] = ($filearrayindatabase[$key2]['position'] ? $filearrayindatabase[$key2]['position'] : '0').'_'.$filearrayindatabase[$key2]['name'];
$filearray[$key]['position'] = $filearrayindatabase[$key2]['position'];
@@ -349,7 +351,7 @@ function completeFileArrayWithDatabaseInfo(&$filearray, $relativedir)
$filearray[$key]['acl'] = '';
$rel_filename = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filearray[$key]['fullname']);
- if (!preg_match('/([\\/]temp[\\/]|[\\/]thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file
+ if (!preg_match('/([\\/]temp[\\/]|[\\/]thumbs|\.meta$)/', $rel_filename)) // If not a tmp file
{
dol_syslog("list_of_documents We found a file called '".$filearray[$key]['name']."' not indexed into database. We add it");
include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
@@ -870,7 +872,7 @@ function dol_move($srcfile, $destfile, $newmask = 0, $overwriteifexists = 1, $te
{
$rel_filetorenamebefore = preg_replace('/^[\\/]/', '', $rel_filetorenamebefore);
$rel_filetorenameafter = preg_replace('/^[\\/]/', '', $rel_filetorenameafter);
- //var_dump($rel_filetorenamebefore.' - '.$rel_filetorenameafter);
+ //var_dump($rel_filetorenamebefore.' - '.$rel_filetorenameafter);exit;
dol_syslog("Try to rename also entries in database for full relative path before = ".$rel_filetorenamebefore." after = ".$rel_filetorenameafter, LOG_DEBUG);
include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
@@ -893,6 +895,7 @@ function dol_move($srcfile, $destfile, $newmask = 0, $overwriteifexists = 1, $te
$ecmfile->filepath = $rel_dir;
$ecmfile->filename = $filename;
+
$resultecm = $ecmfile->update($user);
}
elseif ($resultecm == 0) // If no entry were found for src files, create/update target file
@@ -995,7 +998,7 @@ function dolCheckVirus($src_file)
* @param integer $uploaderrorcode Value of PHP upload error code ($_FILES['field']['error'])
* @param int $nohook Disable all hooks
* @param string $varfiles _FILES var name
- * @return int|string >0 if OK, <0 or string if KO
+ * @return int|string 1 if OK, 2 if OK and .noexe appended, <0 or string if KO
* @see dol_move()
*/
function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan = 0, $uploaderrorcode = 0, $nohook = 0, $varfiles = 'addedfile')
@@ -1005,6 +1008,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable
$reshook = 0;
$file_name = $dest_file;
+ $successcode = 1;
if (empty($nohook))
{
@@ -1055,6 +1059,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable
if (isAFileWithExecutableContent($dest_file) && empty($conf->global->MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED))
{
$file_name .= '.noexe';
+ $successcode = 2;
}
// Security:
@@ -1109,7 +1114,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable
{
if (!empty($conf->global->MAIN_UMASK)) @chmod($file_name_osencoded, octdec($conf->global->MAIN_UMASK));
dol_syslog("Files.lib::dol_move_uploaded_file Success to move ".$src_file." to ".$file_name." - Umask=".$conf->global->MAIN_UMASK, LOG_DEBUG);
- return 1; // Success
+ return $successcode; // Success
}
else
{
@@ -1118,7 +1123,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable
}
}
- return 1; // Success
+ return $successcode; // Success
}
/**
@@ -1173,8 +1178,6 @@ function dol_delete_file($file, $disableglob = 0, $nophperrors = 0, $nohook = 0,
}
else
{
- $error = 0;
-
//print "x".$file." ".$disableglob;exit;
$file_osencoded = dol_osencode($file); // New filename encoded in OS filesystem encoding charset
if (empty($disableglob) && !empty($file_osencoded))
@@ -1197,10 +1200,11 @@ function dol_delete_file($file, $disableglob = 0, $nophperrors = 0, $nohook = 0,
$rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filename);
if (!preg_match('/(\/temp\/|\/thumbs\/|\.meta$)/', $rel_filetodelete)) // If not a tmp file
{
- $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete);
-
if (is_object($db) && $indexdatabase) // $db may not be defined when lib is in a context with define('NOREQUIREDB',1)
{
+ $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete);
+ $rel_filetodelete = preg_replace('/\.noexe$/', '', $rel_filetodelete);
+
dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG);
include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
$ecmfile = new EcmFiles($db);
@@ -1527,6 +1531,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite = 0, $donotupdatesess
if (!empty($_FILES[$varfiles])) // For view $_FILES[$varfiles]['error']
{
dol_syslog('dol_add_file_process upload_dir='.$upload_dir.' allowoverwrite='.$allowoverwrite.' donotupdatesession='.$donotupdatesession.' savingdocmask='.$savingdocmask, LOG_DEBUG);
+
if (dol_mkdir($upload_dir) >= 0)
{
$TFile = $_FILES[$varfiles];
@@ -1552,6 +1557,13 @@ function dol_add_file_process($upload_dir, $allowoverwrite = 0, $donotupdatesess
$destfile=preg_replace('/__file__/', $TFile['name'][$i], $savingdocmask);
}
+ $filenameto = basename($destfile);
+ if (preg_match('/^\./', $filenameto)) {
+ $langs->load("errors"); // key must be loaded because we can't rely on loading during output, we need var substitution to be done now.
+ setEventMessages($langs->trans("ErrorFilenameCantStartWithDot", $filenameto), null, 'errors');
+ break;
+ }
+
// dol_sanitizeFileName the file name and lowercase extension
$info = pathinfo($destfull);
$destfull = $info['dirname'].'/'.dol_sanitizeFileName($info['filename'].($info['extension']!='' ? ('.'.strtolower($info['extension'])) : ''));
@@ -1564,6 +1576,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite = 0, $donotupdatesess
$destfile = dol_string_nohtmltag($destfile);
$destfull = dol_string_nohtmltag($destfull);
+ // Move file from temp directory to final directory. A .noexe may also be appended on file name.
$resupload = dol_move_uploaded_file($TFile['tmp_name'][$i], $destfull, $allowoverwrite, 0, $TFile['error'][$i], 0, $varfiles);
if (is_numeric($resupload) && $resupload > 0) // $resupload can be 'ErrorFileAlreadyExists'
@@ -1600,10 +1613,10 @@ function dol_add_file_process($upload_dir, $allowoverwrite = 0, $donotupdatesess
// Update table of files
if ($donotupdatesession == 1)
{
- $result = addFileIntoDatabaseIndex($upload_dir, basename($destfile), $TFile['name'][$i], 'uploaded', 0);
+ $result = addFileIntoDatabaseIndex($upload_dir, basename($destfile).($resupload == 2 ? '.noexe' : ''), $TFile['name'][$i], 'uploaded', 0);
if ($result < 0)
{
- setEventMessages('FailedToAddFileIntoDatabaseIndex', '', 'warnings');
+ setEventMessages('WarningFailedToAddFileIntoDatabaseIndex', '', 'warnings');
}
}
@@ -1714,7 +1727,7 @@ function dol_remove_file_process($filenb, $donotupdatesession = 0, $donotdeletef
* See also commonGenerateDocument that also add/update database index when a file is generated.
*
* @param string $dir Directory name (full real path without ending /)
- * @param string $file File name
+ * @param string $file File name (May end with '.noexe')
* @param string $fullpathorig Full path of origin for file (can be '')
* @param string $mode How file was created ('uploaded', 'generated', ...)
* @param int $setsharekey Set also the share key
@@ -1730,7 +1743,7 @@ function addFileIntoDatabaseIndex($dir, $file, $fullpathorig = '', $mode = 'uplo
if (!preg_match('/[\\/]temp[\\/]|[\\/]thumbs|\.meta$/', $rel_dir)) // If not a tmp dir
{
- $filename = basename($file);
+ $filename = basename(preg_replace('/\.noexe$/', '', $file));
$rel_dir = preg_replace('/[\\/]$/', '', $rel_dir);
$rel_dir = preg_replace('/^[\\/]/', '', $rel_dir);
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 37dbcbf5ded..69a31d73d31 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -8562,15 +8562,16 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u
/**
* Return if a file can contains executable content
*
- * @param string $filename File NamedRange
+ * @param string $filename File name to test
* @return boolean True if yes, False if no
*/
function isAFileWithExecutableContent($filename)
{
- if (preg_match('/\.(htm|html|js|php|php\d+|phtml|pl|py|cgi|ksh|sh|bash|bat|cmd|wpk|exe|dmg)$/i', $filename))
+ if (preg_match('/\.(htm|html|js|phar|php|php\d+|phtml|pht|pl|py|cgi|ksh|sh|shtml|bash|bat|cmd|wpk|exe|dmg)$/i', $filename))
{
return true;
}
+
return false;
}
diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php
index 0c8f6fceca5..225dab1332c 100644
--- a/htdocs/core/lib/security.lib.php
+++ b/htdocs/core/lib/security.lib.php
@@ -277,9 +277,12 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
if (!$readok) accessforbidden();
//print "Read access is ok";
- // Check write permission from module (we need to know write permission to create but also to delete drafts record)
+ // Check write permission from module (we need to know write permission to create but also to delete drafts record or to upload files)
$createok = 1; $nbko = 0;
- if (GETPOST('action', 'aZ09') == 'create' || GETPOST('action', 'aZ09') == 'update' || ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete'))
+ $wemustcheckpermissionforcreate = (GETPOST('sendit', 'alpha') || GETPOST('linkit', 'alpha') || GETPOST('action', 'aZ09') == 'create' || GETPOST('action', 'aZ09') == 'update');
+ $wemustcheckpermissionfordeletedraft = ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete');
+
+ if ($wemustcheckpermissionforcreate || $wemustcheckpermissionfordeletedraft)
{
foreach ($featuresarray as $feature)
{
@@ -306,6 +309,10 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
elseif ($feature == 'cheque')
{
if (!$user->rights->banque->cheque) { $createok = 0; $nbko++; }
+ } elseif ($feature == 'import') {
+ if (!$user->rights->import->run) { $createok = 0; $nbko++; }
+ } elseif ($feature == 'ecm') {
+ if (!$user->rights->ecm->upload) { $createok = 0; $nbko++; }
}
elseif (!empty($feature2)) // This is for permissions on one level
{
@@ -341,7 +348,7 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
// If a or and at least one ok
if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $createok = 1;
- if ((GETPOST('action', 'aZ09') == 'create' || GETPOST('action', 'aZ09') == 'update') && !$createok) accessforbidden();
+ if ($wemustcheckpermissionforcreate && !$createok) accessforbidden();
//print "Write access is ok";
}
diff --git a/htdocs/core/lib/ticket.lib.php b/htdocs/core/lib/ticket.lib.php
index fe7fb4ba5a7..48b9a7d9089 100644
--- a/htdocs/core/lib/ticket.lib.php
+++ b/htdocs/core/lib/ticket.lib.php
@@ -427,7 +427,7 @@ function show_ticket_messaging($conf, $langs, $db, $filterobj, $objcon = '', $no
$langs->load("mails");
$sql2 = "SELECT m.rowid as id, m.titre as label, mc.date_envoi as dp, mc.date_envoi as dp2, '100' as percent, 'mailing' as type";
- $sql2 .= ", '' as fk_element, '' as elementtype, '' as contact_id";
+ $sql2 .= ", null as fk_element, '' as elementtype, null as contact_id";
$sql2 .= ", 'AC_EMAILING' as acode, '' as alabel, '' as apicto";
$sql2 .= ", u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname"; // User that valid action
if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql2 .= ", '' as lastname, '' as firstname";
diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
index bfa15ebd4b1..a32ba1308a3 100644
--- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
@@ -1275,7 +1275,7 @@ class pdf_crabe extends ModelePDFFactures
$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);
+ $pdf->MultiCell($largcol2, $tab2_hl, price(price2num($tvaval, 'MT'), 0, $outputlangs), 0, 'R', 1);
}
}
diff --git a/htdocs/core/modules/modContrat.class.php b/htdocs/core/modules/modContrat.class.php
index fe846c1fd4c..4d51b4c4247 100644
--- a/htdocs/core/modules/modContrat.class.php
+++ b/htdocs/core/modules/modContrat.class.php
@@ -214,7 +214,7 @@ class modContrat extends DolibarrModules
*/
public function init($options = '')
{
- global $conf;
+ global $conf, $langs;
// Nettoyage avant activation
$this->remove($options);
diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php
index b8539ad41c1..316000293e7 100644
--- a/htdocs/core/modules/modFournisseur.class.php
+++ b/htdocs/core/modules/modFournisseur.class.php
@@ -297,6 +297,14 @@ class modFournisseur extends DolibarrModules
'p.ref'=>'ProductRef','p.label'=>'ProductLabel','p.accountancy_code_buy'=>'ProductAccountancyBuyCode','project.rowid'=>'ProjectId',
'project.ref'=>'ProjectRef','project.title'=>'ProjectLabel'
);
+ if (! empty($conf->multicurrency->enabled))
+ {
+ $this->export_fields_array[$r]['f.multicurrency_code'] = 'Currency';
+ $this->export_fields_array[$r]['f.multicurrency_tx'] = 'CurrencyRate';
+ $this->export_fields_array[$r]['f.multicurrency_total_ht'] = 'MulticurrencyAmountHT';
+ $this->export_fields_array[$r]['f.multicurrency_total_tva'] = 'MulticurrencyAmountVAT';
+ $this->export_fields_array[$r]['f.multicurrency_total_ttc'] = 'MulticurrencyAmountTTC';
+ }
//$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',
// 's.ape'=>'Text','s.idprof4'=>'Text','s.tva_intra'=>'Text','f.ref'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.total_ht'=>"Numeric",'f.total_ttc'=>"Numeric",'f.total_tva'=>"Numeric",
@@ -423,6 +431,14 @@ class modFournisseur extends DolibarrModules
'f.fk_statut'=>'InvoiceStatus','f.note_public'=>"InvoiceNote",'p.rowid'=>'PaymentId','pf.amount'=>'AmountPayment',
'p.datep'=>'DatePayment','p.num_paiement'=>'PaymentNumber','p.fk_bank'=>'IdTransaction','project.rowid'=>'ProjectId','project.ref'=>'ProjectRef','project.title'=>'ProjectLabel'
);
+ if (! empty($conf->multicurrency->enabled))
+ {
+ $this->export_fields_array[$r]['f.multicurrency_code'] = 'Currency';
+ $this->export_fields_array[$r]['f.multicurrency_tx'] = 'CurrencyRate';
+ $this->export_fields_array[$r]['f.multicurrency_total_ht'] = 'MulticurrencyAmountHT';
+ $this->export_fields_array[$r]['f.multicurrency_total_tva'] = 'MulticurrencyAmountVAT';
+ $this->export_fields_array[$r]['f.multicurrency_total_ttc'] = 'MulticurrencyAmountTTC';
+ }
//$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','s.ape'=>'Text','s.idprof4'=>'Text','s.tva_intra'=>'Text','f.ref'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",
@@ -508,6 +524,14 @@ class modFournisseur extends DolibarrModules
'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->multicurrency->enabled))
+ {
+ $this->export_fields_array[$r]['f.multicurrency_code'] = 'Currency';
+ $this->export_fields_array[$r]['f.multicurrency_tx'] = 'CurrencyRate';
+ $this->export_fields_array[$r]['f.multicurrency_total_ht'] = 'MulticurrencyAmountHT';
+ $this->export_fields_array[$r]['f.multicurrency_total_tva'] = 'MulticurrencyAmountVAT';
+ $this->export_fields_array[$r]['f.multicurrency_total_ttc'] = 'MulticurrencyAmountTTC';
+ }
if (empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED))
{
unset($this->export_fields_array['f.date_approve2']);
diff --git a/htdocs/core/tpl/filemanager.tpl.php b/htdocs/core/tpl/filemanager.tpl.php
index 3a3395432de..f95286bbcfc 100644
--- a/htdocs/core/tpl/filemanager.tpl.php
+++ b/htdocs/core/tpl/filemanager.tpl.php
@@ -178,7 +178,7 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
print '';
}
- else // Show filtree when ajax is disabled (rare)
+ else // Show file tree when ajax is disabled (rare)
{
print '';
@@ -212,7 +212,7 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
entity = trim($this->entity);
}
if (isset($this->filename)) {
- $this->filename = trim($this->filename);
+ $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
}
if (isset($this->filepath)) {
$this->filepath = trim($this->filepath);
@@ -346,12 +346,13 @@ class EcmFiles extends CommonObject
$sql .= " t.src_object_id";
$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
$sql.= ' WHERE 1 = 1';
- /* Fetching this table depends on filepath+filename, it must not depends on entity
+ /* Fetching this table depends on filepath+filename, it must not depends on entity because filesystem on disk does not know what is Dolibarr entities
if (! empty($conf->multicompany->enabled)) {
$sql .= " AND entity IN (" . getEntity('ecmfiles') . ")";
}*/
if ($relativepath) {
- $sql .= " AND t.filepath = '" . $this->db->escape(dirname($relativepath)) . "' AND t.filename = '".$this->db->escape(basename($relativepath))."'";
+ $relativepathwithnoexe = preg_replace('/\.noexe$/', '', $relativepath); // We must never have the .noexe into the database
+ $sql .= " AND t.filepath = '" . $this->db->escape(dirname($relativepath)) . "' AND t.filename = '".$this->db->escape(basename($relativepathwithnoexe))."'";
$sql .= " AND t.entity = ".$conf->entity; // unique key include the entity so each company has its own index
}
elseif (! empty($ref)) { // hash of file path
@@ -552,46 +553,47 @@ class EcmFiles extends CommonObject
// Clean parameters
if (isset($this->ref)) {
- $this->ref = trim($this->ref);
+ $this->ref = trim($this->ref);
}
if (isset($this->label)) {
- $this->label = trim($this->label);
+ $this->label = trim($this->label);
}
if (isset($this->share)) {
- $this->share = trim($this->share);
+ $this->share = trim($this->share);
}
if (isset($this->entity)) {
- $this->entity = trim($this->entity);
+ $this->entity = trim($this->entity);
}
if (isset($this->filename)) {
- $this->filename = trim($this->filename);
+ $this->filename = preg_replace('/\.noexe$/', '', trim($this->filename));
}
if (isset($this->filepath)) {
- $this->filepath = trim($this->filepath);
+ $this->filepath = trim($this->filepath);
+ $this->filepath = preg_replace('/[\\/]+$/', '', $this->filepath); // Remove last /
}
if (isset($this->fullpath_orig)) {
- $this->fullpath_orig = trim($this->fullpath_orig);
+ $this->fullpath_orig = trim($this->fullpath_orig);
}
if (isset($this->description)) {
- $this->description = trim($this->description);
+ $this->description = trim($this->description);
}
if (isset($this->keywords)) {
- $this->keywords = trim($this->keywords);
+ $this->keywords = trim($this->keywords);
}
if (isset($this->cover)) {
- $this->cover = trim($this->cover);
+ $this->cover = trim($this->cover);
}
if (isset($this->gen_or_uploaded)) {
- $this->gen_or_uploaded = trim($this->gen_or_uploaded);
+ $this->gen_or_uploaded = trim($this->gen_or_uploaded);
}
if (isset($this->extraparams)) {
- $this->extraparams = trim($this->extraparams);
+ $this->extraparams = trim($this->extraparams);
}
if (isset($this->fk_user_m)) {
- $this->fk_user_m = trim($this->fk_user_m);
+ $this->fk_user_m = trim($this->fk_user_m);
}
if (isset($this->acl)) {
- $this->acl = trim($this->acl);
+ $this->acl = trim($this->acl);
}
if (isset($this->src_object_type)) {
$this->src_object_type = trim($this->src_object_type);
diff --git a/htdocs/ecm/file_card.php b/htdocs/ecm/file_card.php
index 3664a2e7f28..e1796068370 100644
--- a/htdocs/ecm/file_card.php
+++ b/htdocs/ecm/file_card.php
@@ -139,6 +139,12 @@ if ($action == 'update')
$oldfile = $olddir.$oldlabel;
$newfile = $newdir.$newlabel;
+ $newfileformove = $newfile;
+ // If old file end with .noexe, new file must also end with .noexe
+ if (preg_match('/\.noexe$/', $oldfile) && ! preg_match('/\.noexe$/', $newfileformove)) {
+ $newfileformove .= '.noexe';
+ }
+ //var_dump($oldfile);var_dump($newfile);exit;
// Now we update index of file
$db->begin();
@@ -146,7 +152,7 @@ if ($action == 'update')
//print $oldfile.' - '.$newfile;
if ($newlabel != $oldlabel)
{
- $result = dol_move($oldfile, $newfile); // This include update of database
+ $result = dol_move($oldfile, $newfileformove); // This include update of database
if (!$result)
{
$langs->load('errors');
@@ -190,7 +196,7 @@ if ($action == 'update')
$object->entity = $conf->entity;
$object->filepath = preg_replace('/[\\/]+$/', '', $newdirrelativetodocument);
$object->filename = $newlabel;
- $object->label = md5_file(dol_osencode($newfile)); // hash of file content
+ $object->label = md5_file(dol_osencode($newfileformove)); // hash of file content
$object->fullpath_orig = '';
$object->gen_or_uploaded = 'unknown';
$object->description = ''; // indexed content
@@ -208,6 +214,11 @@ if ($action == 'update')
$db->commit();
$urlfile = $newlabel;
+ // If old file end with .noexe, new file must also end with .noexe
+ if (preg_match('/\.noexe$/', $newfileformove)) {
+ $urlfile .= '.noexe';
+ }
+
header('Location: '.$_SERVER["PHP_SELF"].'?urlfile='.urlencode($urlfile).'§ion='.urlencode($section));
exit;
}
@@ -264,9 +275,13 @@ while ($tmpecmdir && $result > 0)
$i++;
}
+$urlfiletoshow = preg_replace('/\.noexe$/', '', $urlfile);
+
$s = img_picto('', 'object_dir').'
'.$langs->trans("ECMRoot").' -> '.$s.' -> ';
-if ($action == 'edit') $s .= '
';
-else $s .= $urlfile;
+if ($action == 'edit') $s .= '
';
+else $s .= $urlfiletoshow;
+
+$morehtml = '';
$object->ref = ''; // Force to hide ref
dol_banner_tab($object, '', $morehtml, 0, '', '', $s);
@@ -289,10 +304,9 @@ print dol_print_size($totalsize);
print '
';
*/
+// Hash of file content
print ''.$langs->trans("HashOfFileContent").' ';
$object = new EcmFiles($db);
-//$filenametosearch=basename($filepath);
-//$filedirtosearch=basedir($filepath);
$object->fetch(0, '', $filepathtodocument);
if (!empty($object->label))
{
diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php
index e51efb01aaa..852d148e258 100644
--- a/htdocs/ecm/index.php
+++ b/htdocs/ecm/index.php
@@ -124,15 +124,17 @@ if ($action == 'confirm_deletefile')
if (GETPOST('confirm') == 'yes')
{
// GETPOST('urlfile','alpha') is full relative URL from ecm root dir. Contains path of all sections.
- //var_dump(GETPOST('urlfile'));exit;
$upload_dir = $conf->ecm->dir_output.($relativepath?'/'.$relativepath:'');
$file = $upload_dir . "/" . GETPOST('urlfile', 'alpha');
+ //var_dump($file);exit;
$ret=dol_delete_file($file); // This include also the delete from file index in database.
if ($ret)
{
- setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile', 'alpha')), null, 'mesgs');
+ $urlfiletoshow = GETPOST('urlfile', 'alpha');
+ $urlfiletoshow = preg_replace('/\.noexe$/', '', $urlfiletoshow);
+ setEventMessages($langs->trans("FileWasRemoved", $urlfiletoshow), null, 'mesgs');
$result=$ecmdir->changeNbOfFiles('-');
}
else
diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php
index 048bdb5d493..5e93397fe66 100644
--- a/htdocs/expensereport/class/expensereport.class.php
+++ b/htdocs/expensereport/class/expensereport.class.php
@@ -2318,7 +2318,7 @@ class ExpenseReport extends CommonObject
public function load_state_board()
{
// phpcs:enable
- global $conf;
+ global $conf, $user;
$this->nb = array();
@@ -2326,6 +2326,12 @@ class ExpenseReport extends CommonObject
$sql .= " FROM ".MAIN_DB_PREFIX."expensereport as ex";
$sql .= " WHERE ex.fk_statut > 0";
$sql .= " AND ex.entity IN (".getEntity('expensereport').")";
+ if (empty($user->rights->expensereport->readall))
+ {
+ $userchildids = $user->getAllChildIds(1);
+ $sql .= " AND (ex.fk_user_author IN (".join(',', $userchildids).")";
+ $sql .= " OR ex.fk_user_validator IN (".join(',', $userchildids)."))";
+ }
$resql = $this->db->query($sql);
if ($resql) {
@@ -2360,15 +2366,17 @@ class ExpenseReport extends CommonObject
$now = dol_now();
- $userchildids = $user->getAllChildIds(1);
-
$sql = "SELECT ex.rowid, ex.date_valid";
$sql .= " FROM ".MAIN_DB_PREFIX."expensereport as ex";
if ($option == 'toapprove') $sql .= " WHERE ex.fk_statut = 2";
else $sql .= " WHERE ex.fk_statut = 5";
$sql .= " AND ex.entity IN (".getEntity('expensereport').")";
- $sql .= " AND (ex.fk_user_author IN (".join(',', $userchildids).")";
- $sql .= " OR ex.fk_user_validator IN (".join(',', $userchildids)."))";
+ if (empty($user->rights->expensereport->readall))
+ {
+ $userchildids = $user->getAllChildIds(1);
+ $sql .= " AND (ex.fk_user_author IN (".join(',', $userchildids).")";
+ $sql .= " OR ex.fk_user_validator IN (".join(',', $userchildids)."))";
+ }
$resql = $this->db->query($sql);
if ($resql)
diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php
index fd45d2daecb..ef6b9241c8d 100644
--- a/htdocs/fichinter/list.php
+++ b/htdocs/fichinter/list.php
@@ -75,8 +75,6 @@ $pagenext = $page + 1;
if (!$sortorder) $sortorder = "DESC";
if (!$sortfield)
{
- //if (empty($conf->global->FICHINTER_DISABLE_DETAILS)) $sortfield="fd.date";
- //else
$sortfield = "f.ref";
}
@@ -203,7 +201,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,";
+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";
if (!empty($conf->projet->enabled)) {
$sql .= ", pr.rowid as projet_id, pr.ref as projet_ref, pr.title as projet_title";
@@ -245,7 +243,7 @@ if ($search_contrat_ref) {
$sql .= natural_search('c.ref', $search_contrat_ref);
}
if ($search_desc) {
- if (empty($conf->global->FICHINTER_DISABLE_DETAILS)) $sql .= natural_search(array('f.description', 'fd.description'), $search_desc);
+ if (empty($conf->global->FICHINTER_DISABLE_DETAILS) && $atleastonefieldinlines) $sql .= natural_search(array('f.description', 'fd.description'), $search_desc);
else $sql .= natural_search(array('f.description'), $search_desc);
}
if ($search_status != '' && $search_status >= 0) {
diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php
index 0352963b13e..2acaad4ec29 100644
--- a/htdocs/filefunc.inc.php
+++ b/htdocs/filefunc.inc.php
@@ -31,7 +31,7 @@
*/
if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE', 'Dolibarr');
-if (! defined('DOL_VERSION')) define('DOL_VERSION', '11.0.4'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
+if (! defined('DOL_VERSION')) define('DOL_VERSION', '11.0.5'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
if (! defined('EURO')) define('EURO', chr(128));
diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php
index 7de6f6a770e..bc975a9267a 100644
--- a/htdocs/fourn/class/fournisseur.commande.class.php
+++ b/htdocs/fourn/class/fournisseur.commande.class.php
@@ -330,7 +330,7 @@ class CommandeFournisseur extends CommonOrder
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON c.fk_mode_reglement = p.id";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_input_method as cm ON cm.rowid = c.fk_input_method";
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON c.fk_incoterms = i.rowid';
- $sql .= " WHERE c.entity = ".$conf->entity;
+ $sql .= " WHERE c.entity IN (".getEntity('supplier_order').")";
if ($ref) $sql .= " AND c.ref='".$this->db->escape($ref)."'";
else $sql .= " AND c.rowid=".$id;
@@ -892,6 +892,7 @@ class CommandeFournisseur extends CommonOrder
$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur SET billed = 1';
$sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > '.self::STATUS_DRAFT;
+
if ($this->db->query($sql))
{
if (!$error)
@@ -1881,7 +1882,6 @@ class CommandeFournisseur extends CommonOrder
if ($result < 0)
{
$error++;
- return -1;
}
// End call triggers
}
@@ -1989,6 +1989,7 @@ class CommandeFournisseur extends CommonOrder
{
$this->errors[] = 'ErrorWhenRunningTrigger';
dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
+ $this->db->rollback();
return -1;
}
// End call triggers
diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php
index b18b054a65b..f8f1c0735b6 100644
--- a/htdocs/fourn/class/paiementfourn.class.php
+++ b/htdocs/fourn/class/paiementfourn.class.php
@@ -89,7 +89,7 @@ class PaiementFourn extends Paiement
{
$error=0;
- $sql = 'SELECT p.rowid, p.ref, p.entity, p.datep as dp, p.amount, p.statut, p.fk_bank,';
+ $sql = 'SELECT p.rowid, p.ref, p.entity, p.datep as dp, p.amount, p.statut, p.fk_bank, p.multicurrency_amount,';
$sql.= ' c.code as paiement_code, c.libelle as paiement_type,';
$sql.= ' p.num_paiement as num_payment, p.note, b.fk_account';
$sql.= ' FROM '.MAIN_DB_PREFIX.'paiementfourn as p';
@@ -111,23 +111,24 @@ class PaiementFourn extends Paiement
if ($num > 0)
{
$obj = $this->db->fetch_object($resql);
- $this->id = $obj->rowid;
- $this->ref = $obj->ref;
- $this->entity = $obj->entity;
- $this->date = $this->db->jdate($obj->dp);
- $this->datepaye = $this->db->jdate($obj->dp);
- $this->num_paiement = $obj->num_payment;
- $this->num_payment = $obj->num_payment;
- $this->bank_account = $obj->fk_account;
- $this->fk_account = $obj->fk_account;
- $this->bank_line = $obj->fk_bank;
- $this->montant = $obj->amount;
- $this->amount = $obj->amount;
- $this->note = $obj->note;
- $this->note_private = $obj->note;
- $this->type_code = $obj->paiement_code;
- $this->type_label = $obj->paiement_type;
- $this->statut = $obj->statut;
+ $this->id = $obj->rowid;
+ $this->ref = $obj->ref;
+ $this->entity = $obj->entity;
+ $this->date = $this->db->jdate($obj->dp);
+ $this->datepaye = $this->db->jdate($obj->dp);
+ $this->num_paiement = $obj->num_payment;
+ $this->num_payment = $obj->num_payment;
+ $this->bank_account = $obj->fk_account;
+ $this->fk_account = $obj->fk_account;
+ $this->bank_line = $obj->fk_bank;
+ $this->montant = $obj->amount;
+ $this->amount = $obj->amount;
+ $this->multicurrency_amount = $obj->multicurrency_amount;
+ $this->note = $obj->note;
+ $this->note_private = $obj->note;
+ $this->type_code = $obj->paiement_code;
+ $this->type_label = $obj->paiement_type;
+ $this->statut = $obj->statut;
$error = 1;
}
else
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index 948fd389b60..984e5ec6cf4 100644
--- a/htdocs/fourn/facture/card.php
+++ b/htdocs/fourn/facture/card.php
@@ -44,6 +44,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
if (!empty($conf->product->enabled)) {
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
}
if (!empty($conf->projet->enabled)) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php
index acd4be35b79..2e61c014532 100644
--- a/htdocs/holiday/class/holiday.class.php
+++ b/htdocs/holiday/class/holiday.class.php
@@ -2173,12 +2173,20 @@ class Holiday extends CommonObject
public function load_state_board()
{
// phpcs:enable
+ global $user;
+
$this->nb = array();
$sql = "SELECT count(h.rowid) as nb";
$sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
$sql .= " WHERE h.statut > 1";
$sql .= " AND h.entity IN (".getEntity('holiday').")";
+ if (empty($user->rights->expensereport->read_all))
+ {
+ $userchildids = $user->getAllChildIds(1);
+ $sql.= " AND (h.fk_user IN (".join(',', $userchildids).")";
+ $sql.= " OR h.fk_validator IN (".join(',', $userchildids)."))";
+ }
$resql = $this->db->query($sql);
if ($resql) {
@@ -2212,14 +2220,16 @@ class Holiday extends CommonObject
$now=dol_now();
- $userchildids = $user->getAllChildIds(1);
-
$sql = "SELECT h.rowid, h.date_debut";
$sql.= " FROM ".MAIN_DB_PREFIX."holiday as h";
$sql.= " WHERE h.statut = 2";
$sql.= " AND h.entity IN (".getEntity('holiday').")";
- $sql.= " AND (h.fk_user IN (".join(',', $userchildids).")";
- $sql.= " OR h.fk_validator IN (".join(',', $userchildids)."))";
+ if(!$user->rights->expensereport->read_all)
+ {
+ $userchildids = $user->getAllChildIds(1);
+ $sql.= " AND (h.fk_user IN (".join(',', $userchildids).")";
+ $sql.= " OR h.fk_validator IN (".join(',', $userchildids)."))";
+ }
$resql=$this->db->query($sql);
if ($resql)
diff --git a/htdocs/index.php b/htdocs/index.php
index 250a0c1736b..ec23af5eb34 100644
--- a/htdocs/index.php
+++ b/htdocs/index.php
@@ -322,7 +322,7 @@ if (empty($user->socid) && empty($conf->global->MAIN_DISABLE_GLOBAL_BOXSTATS))
include_once $includes[$key]; // Loading a class cost around 1Mb
$board = new $classe($db);
- $board->load_state_board($user);
+ $board->load_state_board();
$boardloaded[$classe] = $board;
}
else
diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql
index b21429a4d1b..aa5ab65d3ff 100644
--- a/htdocs/install/mysql/migration/repair.sql
+++ b/htdocs/install/mysql/migration/repair.sql
@@ -495,7 +495,7 @@ UPDATE llx_accounting_bookkeeping set date_creation = tms where date_creation IS
UPDATE llx_facturedet SET situation_percent = 100 WHERE situation_percent IS NULL AND fk_prev_id IS NULL;
-- Test inconsistency of data into situation invoices: If it differs, it may be the total_ht that is wrong and situation_percent that is good.
--- select f.rowid, f.type, qty, subprice, situation_percent, total_ht, total_ttc, total_tva, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc, (situation_percent / 100 * subprice * qty * (1 - (fd.remise_percent / 100)))
+-- select f.rowid, f.type, fd.qty, fd.subprice, fd.situation_percent, fd.total_ht, fd.total_ttc, fd.total_tva, fd.multicurrency_total_ht, fd.multicurrency_total_tva, fd.multicurrency_total_ttc, (situation_percent / 100 * subprice * qty * (1 - (fd.remise_percent / 100)))
-- from llx_facturedet as fd, llx_facture as f where fd.fk_facture = f.rowid AND (total_ht - situation_percent / 100 * subprice * qty * (1 - (fd.remise_percent / 100))) > 0.01 and f.type = 5;
@@ -519,3 +519,7 @@ UPDATE llx_facturedet SET situation_percent = 100 WHERE situation_percent IS NUL
-- update llx_societe set code_compta_fournisseur = concat('401', substr(code_fournisseur, 3, 2),substr(code_fournisseur, 8, 5)) where fournisseur in (1,2,3) and code_fournisseur is not null;
+-- To fix a table with error 'ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs'
+--ALTER TABLE llx_tablename ROW_FORMAT=DYNAMIC;
+
+
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index 00e6279349b..f42f128a4d9 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -1828,6 +1828,7 @@ MailToThirdparty=Third parties
MailToMember=Members
MailToUser=Users
MailToProject=Projects page
+MailToTicket=Tickets
ByDefaultInList=Show by default on list view
YouUseLastStableVersion=You use the latest stable version
TitleExampleForMajorRelease=Example of message you can use to announce this major release (feel free to use it on your web sites)
@@ -1977,4 +1978,5 @@ MakeAnonymousPing=Make an anonymous Ping '+1' to the Dolibarr foundation server
FeatureNotAvailableWithReceptionModule=Feature not available when module Reception is enabled
EmailTemplate=Template for email
EMailsWillHaveMessageID=Emails will have a tag 'References' matching this syntax
-FafaIconSocialNetworksDesc=Enter here the code of a FontAwesome icon. If you don't know what is FontAwesome, you can use the generic value fa-address-book.
\ No newline at end of file
+FafaIconSocialNetworksDesc=Enter here the code of a FontAwesome icon. If you don't know what is FontAwesome, you can use the generic value fa-address-book.
+FeatureNotAvailableWithReceptionModule=Feature not available when module Reception is enabled
diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang
index c5b61e50ed6..2055e24f556 100644
--- a/htdocs/langs/en_US/errors.lang
+++ b/htdocs/langs/en_US/errors.lang
@@ -118,7 +118,7 @@ ErrorLoginHasNoEmail=This user has no email address. Process aborted.
ErrorBadValueForCode=Bad value for security code. Try again with new value...
ErrorBothFieldCantBeNegative=Fields %s and %s can't be both negative
ErrorFieldCantBeNegativeOnInvoice=Field %s cannot be negative on this type of invoice. If you need to add a discount line, just create the discount first (from field '%s' in thirdparty card) and apply it to the invoice.
-ErrorLinesCantBeNegativeForOneVATRate=Total of lines can't be negative for a given VAT rate.
+ErrorLinesCantBeNegativeForOneVATRate=Total of lines (net of tax) can't be negative for a given not null VAT rate (Found a negative total for VAT rate %s %%).
ErrorLinesCantBeNegativeOnDeposits=Lines can't be negative in a deposit. You will face problems when you will need to consume the deposit in final invoice if you do so.
ErrorQtyForCustomerInvoiceCantBeNegative=Quantity for line into customer invoices can't be negative
ErrorWebServerUserHasNotPermission=User account %s used to execute web server has no permission for that
@@ -182,6 +182,7 @@ ErrorBadDefinitionOfMenuArrayInModuleDescriptor=Bad Definition Of Menu Array In
ErrorSavingChanges=An error has occurred when saving the changes
ErrorWarehouseRequiredIntoShipmentLine=Warehouse is required on the line to ship
ErrorFileMustHaveFormat=File must have format %s
+ErrorFilenameCantStartWithDot=Filename can't start with a '.'
ErrorSupplierCountryIsNotDefined=Country for this vendor is not defined. Correct this first.
ErrorsThirdpartyMerge=Failed to merge the two records. Request canceled.
ErrorStockIsNotEnoughToAddProductOnOrder=Stock is not enough for product %s to add it into a new order.
@@ -255,3 +256,4 @@ WarningNumberOfRecipientIsRestrictedInMassAction=Warning, number of different re
WarningDateOfLineMustBeInExpenseReportRange=Warning, the date of line is not in the range of the expense report
WarningProjectClosed=Project is closed. You must re-open it first.
WarningSomeBankTransactionByChequeWereRemovedAfter=Some bank transaction were removed after that the receipt including them were generated. So nb of cheques and total of receipt may differ from number and total in list.
+WarningFailedToAddFileIntoDatabaseIndex=Warnin, failed to add file entry into ECM database index table
\ No newline at end of file
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 31e0d5a1c8d..051dde11ff7 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -837,6 +837,7 @@ Sincerely=Sincerely
ConfirmDeleteObject=Are you sure you want to delete this object?
DeleteLine=Delete line
ConfirmDeleteLine=Are you sure you want to delete this line?
+ErrorPDFTkOutputFileNotFound=Error: the file was not generated. Please check that the 'pdftk' command is installed in a directory included in the $PATH environment variable (linux/unix only) or contact your system administrator.
NoPDFAvailableForDocGenAmongChecked=No PDF were available for the document generation among checked record
TooManyRecordForMassAction=Too many records selected for mass action. The action is restricted to a list of %s records.
NoRecordSelected=No record selected
@@ -1017,4 +1018,4 @@ ContactDefault_ticket=Ticket
ContactAddedAutomatically=Contact added from contact thirdparty roles
More=More
ShowDetails=Show details
-CustomReports=Custom reports
\ No newline at end of file
+CustomReports=Custom reports
diff --git a/htdocs/langs/en_US/receptions.lang b/htdocs/langs/en_US/receptions.lang
index 010a7521846..760ff884fa0 100644
--- a/htdocs/langs/en_US/receptions.lang
+++ b/htdocs/langs/en_US/receptions.lang
@@ -43,3 +43,5 @@ ProductQtyInSuppliersReceptionAlreadyRecevied=Product quantity from open supplie
ValidateOrderFirstBeforeReception=You must first validate the order before being able to make receptions.
ReceptionsNumberingModules=Numbering module for receptions
ReceptionsReceiptModel=Document templates for receptions
+NoMorePredefinedProductToDispatch=No more predefined products to dispatch
+
diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang
index 6fdaed0fe48..021f08c51c4 100644
--- a/htdocs/langs/fr_FR/errors.lang
+++ b/htdocs/langs/fr_FR/errors.lang
@@ -119,7 +119,7 @@ ErrorLoginHasNoEmail=Cet utilisateur n'a pas d'email. Impossible de continuer.
ErrorBadValueForCode=Mauvaise valeur saisie pour le code. Réessayez avec une nouvelle valeur...
ErrorBothFieldCantBeNegative=Les champs %s et %s ne peuvent être tous deux négatifs
ErrorFieldCantBeNegativeOnInvoice=Le champ %s ne peut pas être négatif sur ce type de facture. Si vous devez ajouter une ligne de remise, créez d'abord la remise (à partir du champ '%s' dans la fiche du tiers) et appliquez-la à la facture.
-ErrorLinesCantBeNegativeForOneVATRate=Le total des lignes ne peut pas être négatif pour un taux de TVA donné.
+ErrorLinesCantBeNegativeForOneVATRate=Le total des lignes (HT) ne peut pas être négatif pour un taux de TVA donné (Montant total négatif trouvé pour le taux %s %%).
ErrorLinesCantBeNegativeOnDeposits=Les lignes ne peuvent pas être négatives dans un acompte. Si vous le faites, vous rencontrerez des problèmes lorsque vous devrez consommer l'acompte dans la facture finale.
ErrorQtyForCustomerInvoiceCantBeNegative=La quantité d'une ligne ne peut pas être négative dans les factures clients
ErrorWebServerUserHasNotPermission=Le compte d'exécution du serveur web %s n'a pas les permissions pour cela
diff --git a/htdocs/product/card.php b/htdocs/product/card.php
index ad793f4f7d3..59f2eb13170 100644
--- a/htdocs/product/card.php
+++ b/htdocs/product/card.php
@@ -193,7 +193,7 @@ if (empty($reshook))
{
$error = 0;
- if (!GETPOST('label'))
+ if (!GETPOST('label', 'alphanohtml'))
{
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Label')), null, 'errors');
$action = "create";
@@ -217,8 +217,8 @@ if (empty($reshook))
$units = GETPOST('units', 'int');
$object->ref = $ref;
- $object->label = GETPOST('label');
- $object->price_base_type = GETPOST('price_base_type');
+ $object->label = GETPOST('label', 'alphanohtml');
+ $object->price_base_type = GETPOST('price_base_type', 'aZ09');
if ($object->price_base_type == 'TTC')
$object->price_ttc = GETPOST('price');
@@ -293,7 +293,7 @@ if (empty($reshook))
$object->url = GETPOST('url');
$object->note_private = dol_htmlcleanlastbr(GETPOST('note_private', 'none'));
$object->note = $object->note_private; // deprecated
- $object->customcode = GETPOST('customcode', 'alpha');
+ $object->customcode = GETPOST('customcode', 'alphanohtml');
$object->country_id = GETPOST('country_id', 'int');
$object->duration_value = $duration_value;
$object->duration_unit = $duration_unit;
@@ -394,7 +394,7 @@ if (empty($reshook))
$object->oldcopy = clone $object;
$object->ref = $ref;
- $object->label = GETPOST('label');
+ $object->label = GETPOST('label', 'alphanohtml');
$object->description = dol_htmlcleanlastbr(GETPOST('desc', 'none'));
$object->url = GETPOST('url');
if (!empty($conf->global->MAIN_DISABLE_NOTES_TAB))
@@ -975,7 +975,7 @@ else
print ' ';
$tmpcode = '';
if (!empty($modCodeProduct->code_auto)) $tmpcode = $modCodeProduct->getNextValue($object, $type);
- print ''.$langs->trans("Ref").' ';
+ print ''.$langs->trans("Ref").' ';
if ($refalreadyexists)
{
print $langs->trans("RefAlreadyExists");
@@ -983,7 +983,7 @@ else
print ' ';
// Label
- print ''.$langs->trans("Label").' ';
+ print ''.$langs->trans("Label").' ';
// On sell
print ''.$langs->trans("Status").' ('.$langs->trans("Sell").') ';
diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php
index af78ab5b59d..5030722bb73 100644
--- a/htdocs/product/class/html.formproduct.class.php
+++ b/htdocs/product/class/html.formproduct.class.php
@@ -237,13 +237,14 @@ class FormProduct
*/
public function selectWarehouses($selected = '', $htmlname = 'idwarehouse', $filterstatus = '', $empty = 0, $disabled = 0, $fk_product = 0, $empty_label = '', $showstock = 0, $forcecombo = 0, $events = array(), $morecss = 'minwidth200', $exclude = '', $showfullpath = 1, $stockMin = false, $orderBy = 'e.ref')
{
- global $conf,$langs,$user;
+ global $conf,$langs,$user, $hookmanager;
dol_syslog(get_class($this)."::selectWarehouses $selected, $htmlname, $filterstatus, $empty, $disabled, $fk_product, $empty_label, $showstock, $forcecombo, $morecss", LOG_DEBUG);
$out='';
if (empty($conf->global->ENTREPOT_EXTRA_STATUS)) $filterstatus = '';
if (!empty($fk_product)) $this->cache_warehouses = array();
+
$this->loadWarehouses($fk_product, '', $filterstatus, true, $exclude, $stockMin, $orderBy);
$nbofwarehouses=count($this->cache_warehouses);
@@ -282,6 +283,28 @@ class FormProduct
$out.='';
if ($disabled) $out.=' ';
+ $parameters = array(
+ 'selected' => $selected,
+ 'htmlname' => $htmlname,
+ 'filterstatus' => $filterstatus,
+ 'empty' => $empty,
+ 'disabled ' => $disabled,
+ 'fk_product' => $fk_product,
+ 'empty_label' => $empty_label,
+ 'showstock' => $showstock,
+ 'forcecombo' => $forcecombo,
+ 'events' => $events,
+ 'morecss' => $morecss,
+ 'exclude' => $exclude,
+ 'showfullpath' => $showfullpath,
+ 'stockMin' => $stockMin,
+ 'orderBy' => $orderBy
+ );
+
+ $reshook = $hookmanager->executeHooks('selectWarehouses', $parameters, $this);
+ if ($reshook > 0) $out = $hookmanager->resPrint;
+ elseif ($reshook == 0) $out .= $hookmanager->resPrint;
+
return $out;
}
diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php
index f67910cbef4..1fbbe2ecefa 100644
--- a/htdocs/product/composition/card.php
+++ b/htdocs/product/composition/card.php
@@ -70,7 +70,7 @@ if ($cancel) $action ='';
if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->service->creer))
{
$error=0;
- var_dump(GETPOST("max_prod", 'int'));
+
for ($i=0; $i < GETPOST("max_prod", 'int'); $i++)
{
$qty = price2num(GETPOST("prod_qty_".$i, 'alpha'), 'MS');
diff --git a/htdocs/product/stats/facture.php b/htdocs/product/stats/facture.php
index 5ef97845338..00c36d63f9a 100644
--- a/htdocs/product/stats/facture.php
+++ b/htdocs/product/stats/facture.php
@@ -225,7 +225,7 @@ if ($id > 0 || ! empty($ref))
print_liste_field_titre("CustomerCode", $_SERVER["PHP_SELF"], "s.code_client", "", $option, '', $sortfield, $sortorder);
print_liste_field_titre("DateInvoice", $_SERVER["PHP_SELF"], "f.datef", "", $option, 'align="center"', $sortfield, $sortorder);
print_liste_field_titre("Qty", $_SERVER["PHP_SELF"], "d.qty", "", $option, 'align="center"', $sortfield, $sortorder);
- print_liste_field_titre("AmountHT", $_SERVER["PHP_SELF"], "f.total", "", $option, 'align="right"', $sortfield, $sortorder);
+ print_liste_field_titre("AmountHT", $_SERVER["PHP_SELF"], "d.total_ht", "", $option, 'align="right"', $sortfield, $sortorder);
print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "f.paye,f.fk_statut", "", $option, 'align="right"', $sortfield, $sortorder);
print " \n";
diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php
index 03ba46a4068..0b259018cfc 100644
--- a/htdocs/product/stock/class/entrepot.class.php
+++ b/htdocs/product/stock/class/entrepot.class.php
@@ -692,7 +692,7 @@ class Entrepot extends CommonObject
*/
public function getNomUrl($withpicto = 0, $option = '', $showfullpath = 0, $notooltip = 0)
{
- global $conf, $langs;
+ global $conf, $langs, $hookmanager;
$langs->load("stocks");
if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips
@@ -731,6 +731,16 @@ class Entrepot extends CommonObject
if ($withpicto != 2) $result.= ($showfullpath ? $this->get_full_arbo() : (empty($this->label)?$this->libelle:$this->label));
$result .= $linkend;
+ global $action;
+ $hookmanager->initHooks(array('warehousedao'));
+ $parameters = array('id'=>$this->id, 'getnomurl'=>$result, 'withpicto' => $withpicto, 'option' => $option, 'showfullpath' => $showfullpath, 'notooltip'=> $notooltip);
+ $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
+ if ($reshook > 0) {
+ $result = $hookmanager->resPrint;
+ } else {
+ $result .= $hookmanager->resPrint;
+ }
+
return $result;
}
diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php
index 8d98f028d23..7a0472e226d 100644
--- a/htdocs/product/stock/massstockmove.php
+++ b/htdocs/product/stock/massstockmove.php
@@ -34,6 +34,9 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
// Load translation files required by the page
$langs->loadLangs(array('products', 'stocks', 'orders', 'productbatch'));
+//init Hook
+$hookmanager->initHooks(array('massstockmove'));
+
// Security check
if ($user->socid) {
$socid = $user->socid;
diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php
index feba2dbafcb..dbf07c92d01 100644
--- a/htdocs/product/stock/replenish.php
+++ b/htdocs/product/stock/replenish.php
@@ -376,8 +376,11 @@ if ($usevirtualstock)
$sqlExpeditionsCli = "(SELECT ".$db->ifsql("SUM(ed2.qty) IS NULL", "0", "SUM(ed2.qty)")." as qty"; // We need the ifsql because if result is 0 for product p.rowid, we must return 0 and not NULL
$sqlExpeditionsCli .= " FROM ".MAIN_DB_PREFIX."expedition as e2,";
$sqlExpeditionsCli .= " ".MAIN_DB_PREFIX."expeditiondet as ed2,";
+ $sqlExpeditionsCli .= " ".MAIN_DB_PREFIX."commande as c2,";
$sqlExpeditionsCli .= " ".MAIN_DB_PREFIX."commandedet as cd2";
$sqlExpeditionsCli .= " WHERE ed2.fk_expedition = e2.rowid AND cd2.rowid = ed2.fk_origin_line AND e2.entity IN (".getEntity('expedition').")";
+ $sqlExpeditionsCli .= " AND cd2.fk_commande = c2.rowid";
+ $sqlExpeditionsCli .= " AND c2.fk_statut IN (1,2)";
$sqlExpeditionsCli .= " AND cd2.fk_product = p.rowid";
$sqlExpeditionsCli .= " AND e2.fk_statut IN (1,2))";
} else {
diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php
index 7d995965294..fa0507ca190 100644
--- a/htdocs/projet/tasks/list.php
+++ b/htdocs/projet/tasks/list.php
@@ -58,6 +58,7 @@ $search_task_label = GETPOST('search_task_label');
$search_task_description = GETPOST('search_task_description');
$search_project_user = GETPOST('search_project_user');
$search_task_user = GETPOST('search_task_user');
+$search_societe = GETPOST('search_societe');
$mine = $_REQUEST['mode'] == 'mine' ? 1 : 0;
if ($mine) { $search_task_user = $user->id; $mine = 0; }
diff --git a/htdocs/public/notice.php b/htdocs/public/notice.php
index 43344c376aa..9663bff3cf0 100644
--- a/htdocs/public/notice.php
+++ b/htdocs/public/notice.php
@@ -41,9 +41,8 @@ if (! GETPOST('transkey', 'alphanohtml') && ! GETPOST('transphrase', 'alphanohtm
}
else
{
- $langs->load("error");
- $langs->load("other");
+ $langs->loadLangs(array("error", "other"));
- if (GETPOST('transphrase', 'alphanohtml')) print GETPOST('transphrase', 'alphanohtml');
- if (GETPOST('transkey', 'alphanohtml')) print $langs->trans(GETPOST('transkey', 'alphanohtml'));
+ if (GETPOST('transphrase', 'alphanohtml')) print dol_escape_htmltag(GETPOST('transphrase', 'alphanohtml'));
+ elseif (GETPOST('transkey', 'alphanohtml')) print dol_escape_htmltag($langs->trans(GETPOST('transkey', 'alphanohtml')));
}
diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php
index 9cc5febc2ca..a5fca19e99d 100644
--- a/htdocs/societe/card.php
+++ b/htdocs/societe/card.php
@@ -390,23 +390,23 @@ if (empty($reshook))
if (GETPOST("private", 'int') == 1) // Ask to create a contact
{
- $object->particulier = GETPOST("private");
+ $object->particulier = GETPOST("private", 'int');
- $object->name = dolGetFirstLastname(GETPOST('firstname', 'alpha'), GETPOST('name', 'alpha'));
- $object->civility_id = GETPOST('civility_id'); // Note: civility id is a code, not an int
+ $object->name = dolGetFirstLastname(GETPOST('firstname', 'alphanohtml'), GETPOST('name', 'alphanohtml'));
+ $object->civility_id = GETPOST('civility_id', 'alphanohtml'); // Note: civility id is a code, not an int
// Add non official properties
- $object->name_bis = GETPOST('name', 'alpha');
- $object->firstname = GETPOST('firstname', 'alpha');
+ $object->name_bis = GETPOST('name', 'alphanohtml');
+ $object->firstname = GETPOST('firstname', 'alphanohtml');
}
else
{
- $object->name = GETPOST('name', 'alpha');
+ $object->name = GETPOST('name', 'alphanohtml');
}
- $object->entity = (GETPOSTISSET('entity') ?GETPOST('entity', 'int') : $conf->entity);
- $object->name_alias = GETPOST('name_alias');
- $object->address = GETPOST('address');
- $object->zip = GETPOST('zipcode', 'alpha');
- $object->town = GETPOST('town', 'alpha');
+ $object->entity = (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : $conf->entity);
+ $object->name_alias = GETPOST('name_alias', 'alphanohtml');
+ $object->address = GETPOST('address', 'alphanohtml');
+ $object->zip = GETPOST('zipcode', 'alphanohtml');
+ $object->town = GETPOST('town', 'alphanohtml');
$object->country_id = GETPOST('country_id', 'int');
$object->state_id = GETPOST('state_id', 'int');
//$object->skype = GETPOST('skype', 'alpha');
@@ -425,19 +425,19 @@ if (empty($reshook))
$object->fax = GETPOST('fax', 'alpha');
$object->email = trim(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL));
$object->url = trim(GETPOST('url', 'custom', 0, FILTER_SANITIZE_URL));
- $object->idprof1 = trim(GETPOST('idprof1', 'alpha'));
- $object->idprof2 = trim(GETPOST('idprof2', 'alpha'));
- $object->idprof3 = trim(GETPOST('idprof3', 'alpha'));
- $object->idprof4 = trim(GETPOST('idprof4', 'alpha'));
- $object->idprof5 = trim(GETPOST('idprof5', 'alpha'));
- $object->idprof6 = trim(GETPOST('idprof6', 'alpha'));
- $object->prefix_comm = GETPOST('prefix_comm', 'alpha');
+ $object->idprof1 = trim(GETPOST('idprof1', 'alphanohtml'));
+ $object->idprof2 = trim(GETPOST('idprof2', 'alphanohtml'));
+ $object->idprof3 = trim(GETPOST('idprof3', 'alphanohtml'));
+ $object->idprof4 = trim(GETPOST('idprof4', 'alphanohtml'));
+ $object->idprof5 = trim(GETPOST('idprof5', 'alphanohtml'));
+ $object->idprof6 = trim(GETPOST('idprof6', 'alphanohtml'));
+ $object->prefix_comm = GETPOST('prefix_comm', 'alphanohtml');
$object->code_client = GETPOSTISSET('customer_code') ?GETPOST('customer_code', 'alpha') : GETPOST('code_client', 'alpha');
$object->code_fournisseur = GETPOSTISSET('supplier_code') ?GETPOST('supplier_code', 'alpha') : GETPOST('code_fournisseur', 'alpha');
- $object->capital = GETPOST('capital', 'alpha');
- $object->barcode = GETPOST('barcode', 'alpha');
+ $object->capital = GETPOST('capital', 'alphanohtml');
+ $object->barcode = GETPOST('barcode', 'alphanohtml');
- $object->tva_intra = GETPOST('tva_intra', 'alpha');
+ $object->tva_intra = GETPOST('tva_intra', 'alphanohtml');
$object->tva_assuj = GETPOST('assujtva_value', 'alpha');
$object->status = GETPOST('status', 'alpha');
@@ -861,6 +861,11 @@ if (empty($reshook))
$id = $socid;
$object->fetch($socid);
+ // Selection of new fields
+ if (!empty($conf->global->MAIN_DUPLICATE_CONTACTS_TAB_ON_MAIN_CARD) && (empty($conf->global->SOCIETE_DISABLE_CONTACTS) || !empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT))) {
+ include DOL_DOCUMENT_ROOT . '/core/actions_changeselectedfields.inc.php';
+ }
+
// Actions to send emails
$triggersendname = 'COMPANY_SENTBYMAIL';
$paramname = 'socid';
@@ -964,16 +969,16 @@ else
if (GETPOST("type") == 'p') { $object->client = 2; }
if (!empty($conf->fournisseur->enabled) && (GETPOST("type") == 'f' || (GETPOST("type") == '' && !empty($conf->global->THIRDPARTY_SUPPLIER_BY_DEFAULT)))) { $object->fournisseur = 1; }
- $object->name = GETPOST('name', 'alpha');
- $object->name_alias = GETPOST('name_alias', 'alpha');
- $object->firstname = GETPOST('firstname', 'alpha');
+ $object->name = GETPOST('name', 'alphanohtml');
+ $object->name_alias = GETPOST('name_alias', 'alphanohtml');
+ $object->firstname = GETPOST('firstname', 'alphanohtml');
$object->particulier = $private;
- $object->prefix_comm = GETPOST('prefix_comm', 'alpha');
+ $object->prefix_comm = GETPOST('prefix_comm', 'alphanohtml');
$object->client = GETPOST('client', 'int') ?GETPOST('client', 'int') : $object->client;
if (empty($duplicate_code_error)) {
$object->code_client = GETPOST('customer_code', 'alpha');
- $object->fournisseur = GETPOST('fournisseur') ?GETPOST('fournisseur') : $object->fournisseur;
+ $object->fournisseur = GETPOST('fournisseur') ? GETPOST('fournisseur', 'int') : $object->fournisseur;
$object->code_fournisseur = GETPOST('supplier_code', 'alpha');
}
else {
@@ -981,9 +986,9 @@ else
}
- $object->address = GETPOST('address', 'alpha');
- $object->zip = GETPOST('zipcode', 'alpha');
- $object->town = GETPOST('town', 'alpha');
+ $object->address = GETPOST('address', 'alphanohtml');
+ $object->zip = GETPOST('zipcode', 'alphanohtml');
+ $object->town = GETPOST('town', 'alphanohtml');
$object->state_id = GETPOST('state_id', 'int');
//$object->skype = GETPOST('skype', 'alpha');
//$object->twitter = GETPOST('twitter', 'alpha');
@@ -1001,14 +1006,14 @@ else
$object->fax = GETPOST('fax', 'alpha');
$object->email = GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL);
$object->url = GETPOST('url', 'custom', 0, FILTER_SANITIZE_URL);
- $object->capital = GETPOST('capital', 'alpha');
- $object->barcode = GETPOST('barcode', 'alpha');
- $object->idprof1 = GETPOST('idprof1', 'alpha');
- $object->idprof2 = GETPOST('idprof2', 'alpha');
- $object->idprof3 = GETPOST('idprof3', 'alpha');
- $object->idprof4 = GETPOST('idprof4', 'alpha');
- $object->idprof5 = GETPOST('idprof5', 'alpha');
- $object->idprof6 = GETPOST('idprof6', 'alpha');
+ $object->capital = GETPOST('capital', 'alphanohtml');
+ $object->barcode = GETPOST('barcode', 'alphanohtml');
+ $object->idprof1 = GETPOST('idprof1', 'alphanohtml');
+ $object->idprof2 = GETPOST('idprof2', 'alphanohtml');
+ $object->idprof3 = GETPOST('idprof3', 'alphanohtml');
+ $object->idprof4 = GETPOST('idprof4', 'alphanohtml');
+ $object->idprof5 = GETPOST('idprof5', 'alphanohtml');
+ $object->idprof6 = GETPOST('idprof6', 'alphanohtml');
$object->typent_id = GETPOST('typent_id', 'int');
$object->effectif_id = GETPOST('effectif_id', 'int');
$object->civility_id = GETPOST('civility_id', 'alpha');
@@ -1023,7 +1028,7 @@ else
$object->localtax1_value = GETPOST('lt1', 'int');
$object->localtax2_value = GETPOST('lt2', 'int');
- $object->tva_intra = GETPOST('tva_intra', 'alpha');
+ $object->tva_intra = GETPOST('tva_intra', 'alphanohtml');
$object->commercial_id = GETPOST('commercial_id', 'int');
$object->default_lang = GETPOST('default_lang');
@@ -1252,7 +1257,7 @@ else
print ''.$form->editfieldkey('Vendor', 'fournisseur', '', $object, 0, 'string', '', 1).' ';
$default = -1;
if (!empty($conf->global->THIRDPARTY_SUPPLIER_BY_DEFAULT)) $default = 1;
- print $form->selectyesno("fournisseur", (GETPOST('fournisseur', 'int') != '' ?GETPOST('fournisseur', 'int') : (GETPOST("type", 'alpha') == '' ? $default : $object->fournisseur)), 1, 0, (GETPOST("type", 'alpha') == '' ? 1 : 0));
+ print $form->selectyesno("fournisseur", (GETPOST('fournisseur', 'int') != '' ? GETPOST('fournisseur', 'int') : (GETPOST("type", 'alpha') == '' ? $default : $object->fournisseur)), 1, 0, (GETPOST("type", 'alpha') == '' ? 1 : 0));
print ' ';
@@ -1651,15 +1656,15 @@ else
if (GETPOSTISSET('name'))
{
// We overwrite with values if posted
- $object->name = GETPOST('name', 'alpha');
- $object->prefix_comm = GETPOST('prefix_comm', 'alpha');
+ $object->name = GETPOST('name', 'alphanohtml');
+ $object->prefix_comm = GETPOST('prefix_comm', 'alphanohtml');
$object->client = GETPOST('client', 'int');
$object->code_client = GETPOST('customer_code', 'alpha');
$object->fournisseur = GETPOST('fournisseur', 'int');
$object->code_fournisseur = GETPOST('supplier_code', 'alpha');
- $object->address = GETPOST('address', 'alpha');
- $object->zip = GETPOST('zipcode', 'alpha');
- $object->town = GETPOST('town', 'alpha');
+ $object->address = GETPOST('address', 'alphanohtml');
+ $object->zip = GETPOST('zipcode', 'alphanohtml');
+ $object->town = GETPOST('town', 'alphanohtml');
$object->country_id = GETPOST('country_id') ?GETPOST('country_id', 'int') : $mysoc->country_id;
$object->state_id = GETPOST('state_id', 'int');
//$object->skype = GETPOST('skype', 'alpha');
@@ -1678,21 +1683,21 @@ else
$object->fax = GETPOST('fax', 'alpha');
$object->email = GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL);
$object->url = GETPOST('url', 'custom', 0, FILTER_SANITIZE_URL);
- $object->capital = GETPOST('capital', 'alpha');
- $object->idprof1 = GETPOST('idprof1', 'alpha');
- $object->idprof2 = GETPOST('idprof2', 'alpha');
- $object->idprof3 = GETPOST('idprof3', 'alpha');
- $object->idprof4 = GETPOST('idprof4', 'alpha');
- $object->idprof5 = GETPOST('idprof5', 'alpha');
- $object->idprof6 = GETPOST('idprof6', 'alpha');
+ $object->capital = GETPOST('capital', 'alphanohtml');
+ $object->idprof1 = GETPOST('idprof1', 'alphanohtml');
+ $object->idprof2 = GETPOST('idprof2', 'alphanohtml');
+ $object->idprof3 = GETPOST('idprof3', 'alphanohtml');
+ $object->idprof4 = GETPOST('idprof4', 'alphanohtml');
+ $object->idprof5 = GETPOST('idprof5', 'alphanohtml');
+ $object->idprof6 = GETPOST('idprof6', 'alphanohtml');
$object->typent_id = GETPOST('typent_id', 'int');
$object->effectif_id = GETPOST('effectif_id', 'int');
- $object->barcode = GETPOST('barcode', 'alpha');
+ $object->barcode = GETPOST('barcode', 'alphanohtml');
$object->forme_juridique_code = GETPOST('forme_juridique_code', 'int');
$object->default_lang = GETPOST('default_lang', 'alpha');
$object->tva_assuj = GETPOST('assujtva_value', 'int');
- $object->tva_intra = GETPOST('tva_intra', 'alpha');
+ $object->tva_intra = GETPOST('tva_intra', 'alphanohtml');
$object->status = GETPOST('status', 'int');
// Webservices url/key
diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
index 9cc36dbb7b4..a37830b0ed9 100644
--- a/htdocs/societe/class/societe.class.php
+++ b/htdocs/societe/class/societe.class.php
@@ -83,7 +83,8 @@ class Societe extends CommonObject
);
/**
- * @var array List of child tables. To know object to delete on cascade.
+ * @var array List of child tables. To know object to delete on cascade.
+ * if name like with @ClassNAme:FilePathClass;ParentFkFieldName' it will call method deleteByParentField (with parentId as parameters) and FieldName to fetch and delete child object
*/
protected $childtablesoncascade = array(
"societe_prices",
@@ -92,7 +93,7 @@ class Societe extends CommonObject
"product_fournisseur_price",
"product_customer_price_log",
"product_customer_price",
- "socpeople",
+ "@Contact:/contact/class/contact.class.php:fk_soc",
"adherent",
"societe_account",
"societe_rib",
@@ -636,6 +637,12 @@ class Societe extends CommonObject
*/
public $multicurrency_code;
+ /**
+ * @var Account Default BAN account
+ */
+ public $bank_account;
+
+
/**
* Constructor
*
@@ -1671,16 +1678,36 @@ class Societe extends CommonObject
}
}
- foreach ($this->childtablesoncascade as $tabletodelete)
+ if (!$error)
{
- if (!$error)
+ foreach ($this->childtablesoncascade as $tabletodelete)
{
- $sql = "DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete;
- $sql .= " WHERE fk_soc = ".$id;
- if (!$this->db->query($sql))
- {
- $error++;
- $this->errors[] = $this->db->lasterror();
+ $deleteFromObject=explode(':', $tabletodelete);
+ if (count($deleteFromObject)>=2) {
+ $className=str_replace('@', '', $deleteFromObject[0]);
+ $filepath=$deleteFromObject[1];
+ $columnName=$deleteFromObject[2];
+ if (dol_include_once($filepath)) {
+ $child_object = new $className($this->db);
+ $result = $child_object->deleteByParentField($id, $columnName);
+ if ($result < 0) {
+ $error++;
+ $this->errors[] = $child_object->error;
+ break;
+ }
+ } else {
+ $error++;
+ $this->errors[] = 'Cannot include child class file ' .$filepath;
+ break;
+ }
+ } else {
+ $sql = "DELETE FROM " . MAIN_DB_PREFIX . $tabletodelete;
+ $sql .= " WHERE fk_soc = " . $id;
+ if (!$this->db->query($sql)) {
+ $error++;
+ $this->errors[] = $this->db->lasterror();
+ break;
+ }
}
}
}
@@ -4155,6 +4182,17 @@ class Societe extends CommonObject
}
}
+ if (! isset($this->bank_account)) {
+ require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
+ $bac = new CompanyBankAccount($this->db);
+ $result = $bac->fetch(0, $this->id);
+ if ($result > 0) {
+ $this->bank_account = $bac;
+ } else {
+ $this->bank_account = '';
+ }
+ }
+
$modelpath = "core/modules/societe/doc/";
$result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php
index d59581fa914..64ad5de4906 100644
--- a/htdocs/ticket/card.php
+++ b/htdocs/ticket/card.php
@@ -129,11 +129,11 @@ if ($cancel)
if (GETPOST('add', 'alpha') && $user->rights->ticket->write) {
$error = 0;
- if (!GETPOST("subject", 'alpha')) {
+ if (!GETPOST("subject", 'alphanohtml')) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Subject")), null, 'errors');
$action = 'create';
- } elseif (!GETPOST("message", 'alpha')) {
+ } elseif (!GETPOST("message", 'restricthtml')) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Message")), null, 'errors');
$action = 'create';
@@ -142,10 +142,10 @@ if (GETPOST('add', 'alpha') && $user->rights->ticket->write) {
if (!$error) {
$db->begin();
- $object->ref = GETPOST("ref", 'alpha');
+ $object->ref = GETPOST("ref", 'alphanohtml');
$object->fk_soc = GETPOST("socid", 'int') > 0 ? GETPOST("socid", 'int') : 0;
- $object->subject = GETPOST("subject", 'alpha');
- $object->message = GETPOST("message", 'none');
+ $object->subject = GETPOST("subject", 'alphanohtml');
+ $object->message = GETPOST("message", 'restricthtml');
$object->type_code = GETPOST("type_code", 'alpha');
$object->category_code = GETPOST("category_code", 'alpha');
@@ -274,7 +274,7 @@ if (GETPOST('update', 'alpha') && GETPOST('id', 'int') && $user->rights->ticket-
$error++;
array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")));
$action = 'edit';
- } elseif (!GETPOST("subject")) {
+ } elseif (!GETPOST("subject", 'alphanohtml')) {
$error++;
array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Subject")));
$action = 'edit';
@@ -284,7 +284,7 @@ if (GETPOST('update', 'alpha') && GETPOST('id', 'int') && $user->rights->ticket-
$db->begin();
$object->label = GETPOST("label", 'alphanohtml');
- $object->description = GETPOST("description", 'none');
+ $object->description = GETPOST("description", 'restricthtml');
//...
$ret = $object->update($user);
@@ -459,7 +459,7 @@ if ($action == 'set_progression' && $user->rights->ticket->write) {
if ($action == 'setsubject') {
if ($object->fetch(GETPOST('id', 'int'))) {
if ($action == 'setsubject') {
- $object->subject = trim(GETPOST('subject', 'alpha'));
+ $object->subject = trim(GETPOST('subject', 'alphanohtml'));
}
if ($action == 'setsubject' && empty($object->subject)) {
@@ -512,7 +512,7 @@ elseif ($action == 'setcontract' && $user->rights->ticket->write) {
if (!GETPOST('cancel')) {
$object->fetch('', '', GETPOST('track_id', 'alpha'));
$oldvalue_message = $object->message;
- $fieldtomodify = GETPOST('message_initial');
+ $fieldtomodify = GETPOST('message_initial', 'restricthtml');
$object->message = $fieldtomodify;
$ret = $object->update($user);
diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php
index f112cdc7e4e..8ba9351d053 100644
--- a/htdocs/ticket/class/ticket.class.php
+++ b/htdocs/ticket/class/ticket.class.php
@@ -2455,8 +2455,9 @@ class Ticket extends CommonObject
// If destination file already exists, we add a suffix to avoid to overwrite
if (is_file($destfile))
{
- $now = dol_now();
- $destfile .= '.'.dol_print_date($now, 'dayhourlog');
+ $pathinfo = pathinfo($filename[$i]);
+ $now = dol_now();
+ $destfile = $destdir.'/'.$pathinfo['filename'].' - '.dol_print_date($now, 'dayhourlog').'.'.$pathinfo['extension'];
}
$res = dol_move($filepath[$i], $destfile, 0, 1);
diff --git a/htdocs/user/card.php b/htdocs/user/card.php
index 4bedd36fc3c..6e2d9b1cfdb 100644
--- a/htdocs/user/card.php
+++ b/htdocs/user/card.php
@@ -1631,32 +1631,36 @@ else
print "\n";
// Expense report validator
- print '';
- $text = $langs->trans("ForceUserExpenseValidator");
- print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
- print ' ';
- print '';
- if (!empty($object->fk_user_expense_validator)) {
- $evuser = new User($db);
- $evuser->fetch($object->fk_user_expense_validator);
- print $evuser->getNomUrl(1);
+ if (!empty($conf->expensereport->enabled)) {
+ print ' ';
+ $text = $langs->trans("ForceUserExpenseValidator");
+ print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
+ print ' ';
+ print '';
+ if (!empty($object->fk_user_expense_validator)) {
+ $evuser = new User($db);
+ $evuser->fetch($object->fk_user_expense_validator);
+ print $evuser->getNomUrl(1);
+ }
+ print ' ';
+ print " \n";
}
- print '';
- print "\n";
// Holiday request validator
- print '';
- $text = $langs->trans("ForceUserHolidayValidator");
- print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
- print ' ';
- print '';
- if (!empty($object->fk_user_holiday_validator)) {
- $hvuser = new User($db);
- $hvuser->fetch($object->fk_user_holiday_validator);
- print $hvuser->getNomUrl(1);
+ if (!empty($conf->holiday->enabled)) {
+ print ' ';
+ $text = $langs->trans("ForceUserHolidayValidator");
+ print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
+ print ' ';
+ print '';
+ if (!empty($object->fk_user_holiday_validator)) {
+ $hvuser = new User($db);
+ $hvuser->fetch($object->fk_user_holiday_validator);
+ print $hvuser->getNomUrl(1);
+ }
+ print ' ';
+ print " \n";
}
- print '';
- print "\n";
// Default warehouse
if (!empty($conf->stock->enabled) && !empty($conf->global->USER_DEFAULT_WAREHOUSE)) // TODO What is goal of this. How it is used ?
@@ -2345,44 +2349,42 @@ else
print "\n";
// Expense report validator
- print '';
- $text = $langs->trans("ForceUserExpenseValidator");
- print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
- print ' ';
- print '';
- if ($caneditfield)
- {
- print $form->select_dolusers($object->fk_user_expense_validator, 'fk_user_expense_validator', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'maxwidth300');
+ if (!empty($conf->expensereport->enabled)) {
+ print ' ';
+ $text = $langs->trans("ForceUserExpenseValidator");
+ print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
+ print ' ';
+ print '';
+ if ($caneditfield) {
+ print $form->select_dolusers($object->fk_user_expense_validator, 'fk_user_expense_validator', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'maxwidth300');
+ } else {
+ print ' ';
+ $evuser = new User($db);
+ $evuser->fetch($object->fk_user_expense_validator);
+ print $evuser->getNomUrl(1);
+ }
+ print ' ';
+ print " \n";
}
- else
- {
- print ' ';
- $evuser = new User($db);
- $evuser->fetch($object->fk_user_expense_validator);
- print $evuser->getNomUrl(1);
- }
- print '';
- print "\n";
// Holiday request validator
- print '';
- $text = $langs->trans("ForceUserHolidayValidator");
- print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
- print ' ';
- print '';
- if ($caneditfield)
- {
- print $form->select_dolusers($object->fk_user_holiday_validator, 'fk_user_holiday_validator', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'maxwidth300');
+ if (!empty($conf->holiday->enabled)) {
+ print ' ';
+ $text = $langs->trans("ForceUserHolidayValidator");
+ print $form->textwithpicto($text, $langs->trans("ValidatorIsSupervisorByDefault"), 1, 'help');
+ print ' ';
+ print '';
+ if ($caneditfield) {
+ print $form->select_dolusers($object->fk_user_holiday_validator, 'fk_user_holiday_validator', 1, array($object->id), 0, '', 0, $object->entity, 0, 0, '', 0, '', 'maxwidth300');
+ } else {
+ print ' ';
+ $hvuser = new User($db);
+ $hvuser->fetch($object->fk_user_holiday_validator);
+ print $hvuser->getNomUrl(1);
+ }
+ print ' ';
+ print " \n";
}
- else
- {
- print ' ';
- $hvuser = new User($db);
- $hvuser->fetch($object->fk_user_holiday_validator);
- print $hvuser->getNomUrl(1);
- }
- print '';
- print "\n";
print '';
diff --git a/htdocs/variants/ajax/get_attribute_values.php b/htdocs/variants/ajax/get_attribute_values.php
index 866bac1ef78..ee45ad18b23 100644
--- a/htdocs/variants/ajax/get_attribute_values.php
+++ b/htdocs/variants/ajax/get_attribute_values.php
@@ -28,7 +28,7 @@ require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttributeValue.class.php'
header('Content-Type: application/json');
-$id = GETPOST('id');
+$id = GETPOST('id', 'int');
if (!$id) {
print json_encode(array(