\n";
- if (!empty($user->rights->accounting->chartofaccount)) {
+ if ($user->hasRight('accounting', 'chartofaccount')) {
print "
'.$langs->trans("AccountancyAreaDescActionOnce"), '', '')."\n";
diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php
index 44a12293e67..fbc3eefd641 100644
--- a/htdocs/adherents/card.php
+++ b/htdocs/adherents/card.php
@@ -40,6 +40,7 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
@@ -277,7 +278,7 @@ if (empty($reshook)) {
}
// Create new object
if ($result > 0 && !$error) {
- $object->oldcopy = clone $object;
+ $object->oldcopy = dol_clone($object);
// Change values
$object->civility_id = trim(GETPOST("civility_id", 'alphanohtml'));
@@ -311,8 +312,8 @@ if (empty($reshook)) {
//$object->twitter = trim(GETPOST("twitter", 'alpha'));
//$object->facebook = trim(GETPOST("facebook", 'alpha'));
//$object->linkedin = trim(GETPOST("linkedin", 'alpha'));
- $object->birth = $birthdate;
-
+ $object->birth = $birthdate;
+ $object->default_lang = GETPOST('default_lang', 'alpha');
$object->typeid = GETPOST("typeid", 'int');
//$object->note = trim(GETPOST("comment","alpha"));
$object->morphy = GETPOST("morphy", 'alpha');
@@ -457,6 +458,7 @@ if (empty($reshook)) {
$userid = GETPOST("userid", 'int');
$socid = GETPOST("socid", 'int');
+ $default_lang = GETPOST('default_lang', 'alpha');
$object->civility_id = $civility_id;
$object->firstname = $firstname;
@@ -498,7 +500,7 @@ if (empty($reshook)) {
$object->user_id = $userid;
$object->socid = $socid;
$object->public = $public;
-
+ $object->default_lang = $default_lang;
// Fill array 'array_options' with data from add form
$ret = $extrafields->setOptionalsFromPost(null, $object);
if ($ret < 0) {
@@ -580,36 +582,16 @@ if (empty($reshook)) {
$id = $object->id;
} else {
$db->rollback();
+ setEventMessages($object->error, $object->errors, 'errors');
- if ($object->error) {
- setEventMessages($object->error, $object->errors, 'errors');
- } else {
- setEventMessages($object->error, $object->errors, 'errors');
- }
}
+
// Auto-create thirdparty on member creation
if (!empty($conf->global->ADHERENT_DEFAULT_CREATE_THIRDPARTY)) {
if ($result > 0) {
- // User creation
+ // Create third party out of a member
$company = new Societe($db);
-
- $companyalias = '';
- $fullname = $object->getFullName($langs);
-
- if ($object->morphy == 'mor') {
- $companyname = $object->company;
- if (!empty($fullname)) {
- $companyalias = $fullname;
- }
- } else {
- $companyname = $fullname;
- if (!empty($object->company)) {
- $companyalias = $object->company;
- }
- }
-
- $result = $company->create_from_member($object, $companyname, $companyalias);
-
+ $result = $company->create_from_member($object);
if ($result < 0) {
$langs->load("errors");
setEventMessages($langs->trans($company->error), null, 'errors');
@@ -899,6 +881,7 @@ if (empty($reshook)) {
$form = new Form($db);
$formfile = new FormFile($db);
+$formadmin = new FormAdmin($db);
$formcompany = new FormCompany($db);
$title = $langs->trans("Member")." - ".$langs->trans("Card");
@@ -1363,6 +1346,14 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
print $form->selectDate(($object->birth ? $object->birth : -1), 'birth', '', '', 1, 'formsoc');
print "\n";
+ // Default language
+ if (!empty($conf->global->MAIN_MULTILANGS)) {
+ print '
';
+ // Default language
+ if (!empty($conf->global->MAIN_MULTILANGS)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+ print '
';
diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php
index dec7584b68e..318dc4ac794 100644
--- a/htdocs/adherents/class/adherent.class.php
+++ b/htdocs/adherents/class/adherent.class.php
@@ -215,6 +215,12 @@ class Adherent extends CommonObject
*/
public $public;
+ /**
+ * Default language code of member (en_US, ...)
+ * @var string
+ */
+ public $default_lang;
+
/**
* @var string photo of member
*/
@@ -328,6 +334,7 @@ class Adherent extends CommonObject
'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => -1, 'position' => 135),
'public' => array('type' => 'smallint(6)', 'label' => 'Public', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 145),
'datefin' => array('type' => 'datetime', 'label' => 'DateEnd', 'enabled' => 1, 'visible' => -1, 'position' => 150),
+ 'default_lang' =>array('type'=>'varchar(6)', 'label'=>'Default lang', 'enabled'=>1, 'visible'=>-1, 'position'=> 153),
'note_private' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
'note_public' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
'datevalid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 165),
@@ -710,9 +717,11 @@ class Adherent extends CommonObject
$sql .= ", photo = ".($this->photo ? "'".$this->db->escape($this->photo)."'" : "null");
$sql .= ", public = '".$this->db->escape($this->public)."'";
$sql .= ", statut = ".$this->db->escape($this->statut);
+ $sql .= ", default_lang = ".(!empty($this->default_lang) ? "'".$this->db->escape($this->default_lang)."'" : "null");
$sql .= ", fk_adherent_type = ".$this->db->escape($this->typeid);
$sql .= ", morphy = '".$this->db->escape($this->morphy)."'";
$sql .= ", birth = ".($this->birth ? "'".$this->db->idate($this->birth)."'" : "null");
+
if ($this->datefin) {
$sql .= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription
}
@@ -833,6 +842,8 @@ class Adherent extends CommonObject
$luser->office_phone = $this->phone;
$luser->user_mobile = $this->phone_mobile;
+ $luser->lang = $this->default_lang;
+
$luser->fk_member = $this->id;
$result = $luser->update($user, 0, 1, 1); // Use nosync to 1 to avoid cyclic updates
@@ -868,6 +879,7 @@ class Adherent extends CommonObject
$lthirdparty->state_id = $this->state_id;
$lthirdparty->country_id = $this->country_id;
//$lthirdparty->phone_mobile=$this->phone_mobile;
+ $lthirdparty->default_lang = $this->default_lang;
$result = $lthirdparty->update($this->fk_soc, $user, 0, 1, 1, 'update'); // Use sync to 0 to avoid cyclic updates
@@ -1314,7 +1326,7 @@ class Adherent extends CommonObject
$sql .= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
$sql .= " d.datec as datec,";
$sql .= " d.tms as datem,";
- $sql .= " d.datefin as datefin,";
+ $sql .= " d.datefin as datefin, d.default_lang,";
$sql .= " d.birth as birthday,";
$sql .= " d.datevalid as datev,";
$sql .= " d.country,";
@@ -1407,6 +1419,8 @@ class Adherent extends CommonObject
$this->date_validation = $this->db->jdate($obj->datev);
$this->birth = $this->db->jdate($obj->birthday);
+ $this->default_lang = $obj->default_lang;
+
$this->note_private = $obj->note_private;
$this->note_public = $obj->note_public;
$this->morphy = $obj->morphy;
@@ -2556,6 +2570,7 @@ class Adherent extends CommonObject
$this->datefin = $now;
$this->datevalid = $now;
+ $this->default_lang = '';
$this->typeid = 1; // Id type adherent
$this->type = 'Type adherent'; // Libelle type adherent
diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php
index f3d5f96a78a..e37d52480fa 100644
--- a/htdocs/adherents/type.php
+++ b/htdocs/adherents/type.php
@@ -170,7 +170,8 @@ if ($action == 'add' && $user->rights->adherent->configurer) {
if ($action == 'update' && $user->rights->adherent->configurer) {
$object->fetch($rowid);
- $object->oldcopy = clone $object;
+ $object->oldcopy = dol_clone($object);
+
$object->label= trim($label);
$object->morphy = trim($morphy);
$object->status = (int) $status;
diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
index dd29ee1cde3..3cba1a333ca 100644
--- a/htdocs/admin/dict.php
+++ b/htdocs/admin/dict.php
@@ -1220,14 +1220,16 @@ if ($id > 0) {
$sql .= natural_search("code_iso", $search_code);
} elseif ($search_code != '' && $id == 28) {
$sql .= natural_search("h.code", $search_code);
- } elseif ($search_code != '' && $id == 32) {
+ } elseif ($search_code != '' && ($id == 7 || $id == 32)) {
$sql .= natural_search("a.code", $search_code);
} elseif ($search_code != '' && $id == 3) {
$sql .= natural_search("r.code_region", $search_code);
- } elseif ($search_code != '' && $id == 7) {
- $sql .= natural_search("a.code", $search_code);
- } elseif ($search_code != '' && $id == 10) {
+ } elseif ($search_code != '' && ($id == 8 || $id == 10)) {
$sql .= natural_search("t.code", $search_code);
+ } elseif ($search_code != '' && $id == 1) {
+ $sql .= natural_search("f.code", $search_code);
+ } elseif ($search_code != '' && $id == 2) {
+ $sql .= natural_search("d.code_departement", $search_code);
} elseif ($search_code != '' && $id != 9) {
$sql .= natural_search("code", $search_code);
}
diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php
index 67bf775bdd9..0504315075d 100644
--- a/htdocs/admin/mails.php
+++ b/htdocs/admin/mails.php
@@ -88,7 +88,15 @@ if ($action == 'update' && !$cancel) {
dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT", GETPOST("MAIN_MAIL_SMTP_PORT", 'int'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER", GETPOST("MAIN_MAIL_SMTP_SERVER", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID", GETPOST("MAIN_MAIL_SMTPS_ID", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW", 'none'), 'chaine', 0, '', $conf->entity);
+ if (GETPOSTISSET("MAIN_MAIL_SMTPS_PW")) {
+ dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW", 'none'), 'chaine', 0, '', $conf->entity);
+ }
+ if (GETPOSTISSET("MAIN_MAIL_SMTPS_AUTH_TYPE")) {
+ dolibarr_set_const($db, "MAIN_MAIL_SMTPS_AUTH_TYPE", GETPOST("MAIN_MAIL_SMTPS_AUTH_TYPE", 'chaine'), 'chaine', 0, '', $conf->entity);
+ }
+ if (GETPOSTISSET("MAIN_MAIL_SMTPS_OAUTH_SERVICE")) {
+ dolibarr_set_const($db, "MAIN_MAIL_SMTPS_OAUTH_SERVICE", GETPOST("MAIN_MAIL_SMTPS_OAUTH_SERVICE", 'chaine'), 'chaine', 0, '', $conf->entity);
+ }
dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS", GETPOST("MAIN_MAIL_EMAIL_TLS", 'int'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MAIL_EMAIL_STARTTLS", GETPOST("MAIN_MAIL_EMAIL_STARTTLS", 'int'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, "MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED", GETPOST("MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED", 'int'), 'chaine', 0, '', $conf->entity);
@@ -171,6 +179,24 @@ if (version_compare(phpversion(), '7.0', '>=')) {
$listofmethods['swiftmailer'] = 'Swift Mailer socket library';
}
+// List of oauth services
+$oauthservices = array();
+
+foreach ($conf->global as $key => $val) {
+ if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) {
+ $key = preg_replace('/^OAUTH_/', '', $key);
+ $key = preg_replace('/_ID$/', '', $key);
+ if (preg_match('/^.*-/', $key)) {
+ $name = preg_replace('/^.*-/', '', $key);
+ } else {
+ $name = $langs->trans("NoName");
+ }
+ $provider = preg_replace('/-.*$/', '', $key);
+ $provider = ucfirst(strtolower($provider));
+
+ $oauthservices[$key] = $name." (".$provider.")";
+ }
+}
if ($action == 'edit') {
if ($conf->use_javascript_ajax) {
@@ -195,6 +221,7 @@ if ($action == 'edit') {
jQuery("#MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY").prop("disabled", true);
jQuery(".smtp_method").hide();
jQuery(".dkim").hide();
+ jQuery(".smtp_auth_method").hide();
';
if ($linuxlike) {
print '
@@ -237,6 +264,7 @@ if ($action == 'edit') {
jQuery("#smtp_port_mess").hide();
jQuery(".smtp_method").show();
jQuery(".dkim").hide();
+ jQuery(".smtp_auth_method").show();
}
if (jQuery("#MAIN_MAIL_SENDMODE").val()==\'swiftmailer\')
{
@@ -264,12 +292,34 @@ if ($action == 'edit') {
jQuery("#smtp_port_mess").hide();
jQuery(".smtp_method").show();
jQuery(".dkim").show();
+ jQuery(".smtp_auth_method").show();
}
}
+ function change_smtp_auth_method() {
+ console.log(jQuery("#radio_pw").prop("checked"));
+ if (jQuery("#MAIN_MAIL_SENDMODE").val()==\'smtps\' && jQuery("#radio_oauth").prop("checked")) {
+ jQuery(".smtp_oauth_service").show();
+ jQuery(".smtp_pw").hide();
+ } else if (jQuery("#MAIN_MAIL_SENDMODE").val()==\'swiftmailer\' && jQuery("#radio_oauth").prop("checked")) {
+ jQuery(".smtp_oauth_service").show();
+ jQuery(".smtp_pw").hide();
+ } else if(jQuery("#MAIN_MAIL_SENDMODE").val()==\'mail\'){
+ jQuery(".smtp_oauth_service").hide();
+ jQuery(".smtp_pw").hide();
+ } else {
+ jQuery(".smtp_oauth_service").hide();
+ jQuery(".smtp_pw").show();
+ }
+ }
initfields();
+ change_smtp_auth_method();
jQuery("#MAIN_MAIL_SENDMODE").change(function() {
initfields();
+ change_smtp_auth_method();
});
+ jQuery("#radio_pw, #radio_oauth").change(function() {
+ change_smtp_auth_method();
+ });
jQuery("#MAIN_MAIL_EMAIL_TLS").change(function() {
if (jQuery("#MAIN_MAIL_EMAIL_TLS").val() == 1)
jQuery("#MAIN_MAIL_EMAIL_STARTTLS").val(0);
@@ -413,10 +463,29 @@ if ($action == 'edit') {
print '';
}
+
+ // OAUTH
+ if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))) {
+ print '
';
+ }
+
// PW
if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))) {
$mainsmtppw = (!empty($conf->global->MAIN_MAIL_SMTPS_PW) ? $conf->global->MAIN_MAIL_SMTPS_PW : '');
- print '
';
}
+ // OAUTH service provider
+ if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))) {
+ print '
';
// Host server
- if ($linuxlike && (isset($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'mail')) {
+ if ($linuxlike && (getDolGlobalString('MAIN_MAIL_SENDMODE') == 'mail')) {
print '
';
}
+
// Port
- if ($linuxlike && (isset($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'mail')) {
+ if ($linuxlike && (getDolGlobalString('MAIN_MAIL_SENDMODE') == 'mail')) {
print '
';
}
// SMTPS ID
- if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer'))) {
+ if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE'), array('smtps', 'swiftmailer'))) {
print '
';
}
+ // AUTH method
+ if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE'), array('smtps', 'swiftmailer'))) {
+ $authtype = getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE', 'LOGIN');
+ $text = ($authtype === "LOGIN") ? $langs->trans("UsePassword") : ($authtype === "XOAUTH2" ? $langs->trans("UseOauth") : '') ;
+ print '
';
+ }
+
// SMTPS PW
- if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer'))) {
+ if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE'), array('smtps', 'swiftmailer')) && getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE') != "XOAUTH2") {
print '
';
}
+ // SMTPS oauth service
+ if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE'), array('smtps', 'swiftmailer')) && getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE') === "XOAUTH2") {
+ $text = $oauthservices[$conf->global->MAIN_MAIL_SMTPS_OAUTH_SERVICE];
+ if (empty($text)) {
+ $text = $langs->trans("Undefined").img_warning();
+ }
+ print '
'.$langs->trans("MAIN_MAIL_EMAIL_TLS").' ';
if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer'))) {
diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php
index 8e31d0e6d62..db92c33a7fb 100644
--- a/htdocs/admin/mails_senderprofile_list.php
+++ b/htdocs/admin/mails_senderprofile_list.php
@@ -557,6 +557,7 @@ if (!empty($extrafields->attributes[$object->table_element]['computed']) && is_a
// --------------------------------------------------------------------
$i = 0;
$totalarray = array();
+$totalarray['nbfield'] = 0;
while ($i < ($limit ? min($num, $limit) : $num)) {
$obj = $db->fetch_object($resql);
if (empty($obj)) {
diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php
index 286ccc424e8..d04039aefdf 100644
--- a/htdocs/admin/modules.php
+++ b/htdocs/admin/modules.php
@@ -43,10 +43,15 @@ require_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/dolistore.class.php';
// Load translation files required by the page
$langs->loadLangs(array("errors", "admin", "modulebuilder"));
-$mode = GETPOSTISSET('mode') ? GETPOST('mode', 'alpha') : (empty($conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT) ? 'commonkanban' : 'common');
-if (empty($mode)) {
- $mode = 'common';
+// if we set another view list mode, we keep it (till we change one more time)
+if (GETPOSTISSET('mode')) {
+ $mode = GETPOST('mode', 'alpha');
+ if ($mode =='common' || $mode =='commonkanban')
+ dolibarr_set_const($db, "MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT", $mode, 'chaine', 0, '', $conf->entity);
+} else {
+ $mode = (empty($conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT) ? 'commonkanban' : $conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT);
}
+
$action = GETPOST('action', 'aZ09');
$value = GETPOST('value', 'alpha');
$page_y = GETPOST('page_y', 'int');
diff --git a/htdocs/admin/oauth.php b/htdocs/admin/oauth.php
index 772055f0809..ade561c4ef1 100644
--- a/htdocs/admin/oauth.php
+++ b/htdocs/admin/oauth.php
@@ -62,7 +62,7 @@ if ($action == 'add') { // $provider is OAUTH_XXX
setEventMessages($langs->trans("AOAuthEntryForThisProviderAndLabelAlreadyHasAKey"), null, 'errors');
$error++;
} else {
- dolibarr_set_const($db, $constname, 'ToComplete', 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, $constname, $langs->trans('ToComplete'), 'chaine', 0, '', $conf->entity);
setEventMessages($langs->trans("OAuthProviderAdded"), null);
}
}
@@ -78,6 +78,16 @@ if ($action == 'update') {
if (!dolibarr_set_const($db, $constvalue.'_SECRET', GETPOST($constvalue.'_ID') ? GETPOST($constvalue.'_SECRET') : '', 'chaine', 0, '', $conf->entity)) {
$error++;
}
+ if (GETPOSTISSET($constvalue.'_URLAUTHORIZE')) {
+ if (!dolibarr_set_const($db, $constvalue.'_URLAUTHORIZE', GETPOST($constvalue.'_URLAUTHORIZE'), 'chaine', 0, '', $conf->entity)) {
+ $error++;
+ }
+ }
+ if (GETPOSTISSET($constvalue.'_SCOPE')) {
+ if (!dolibarr_set_const($db, $constvalue.'_SCOPE', GETPOST($constvalue.'_SCOPE'), 'chaine', 0, '', $conf->entity)) {
+ $error++;
+ }
+ }
}
}
@@ -147,11 +157,17 @@ print '';
$i = 0;
-//var_dump($list);
+// Define $listinsetup
foreach ($conf->global as $key => $val) {
if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) {
$provider = preg_replace('/_ID$/', '', $key);
- $listinsetup[] = array($provider.'_NAME', $provider.'_ID', $provider.'_SECRET', 'OAUTH Provider '.str_replace('OAUTH_', '', $provider));
+ $listinsetup[] = array(
+ $provider.'_NAME',
+ $provider.'_ID',
+ $provider.'_SECRET',
+ $provider.'_URLAUTHORIZE', // For custom oauth links
+ $provider.'_SCOPE' // For custom oauth links
+ );
}
}
@@ -178,12 +194,16 @@ foreach ($listinsetup as $key) {
$i++;
- print '';
// Api Name
$label = $langs->trans($keyforsupportedoauth2array);
+ print ' ';
print '';
print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"');
- print $label;
+ if ($label == $keyforsupportedoauth2array) {
+ print $supportedoauth2array[$keyforsupportedoauth2array]['name'];
+ } else {
+ print $label;
+ }
if ($keyforprovider) {
print ' ('.$keyforprovider.' )';
} else {
@@ -201,8 +221,15 @@ foreach ($listinsetup as $key) {
$redirect_uri = $urlwithroot.'/core/modules/oauth/'.$supportedoauth2array[$keyforsupportedoauth2array]['callbackfile'].'_oauthcallback.php';
print ' ';
print ''.$langs->trans("UseTheFollowingUrlAsRedirectURI").' ';
- print ' ';
+ print ' ';
print ' ';
+
+ if ($keyforsupportedoauth2array == 'OAUTH_OTHER_NAME') {
+ print '';
+ print ''.$langs->trans("URLOfServiceForAuthorization").' ';
+ print ' ';
+ print ' ';
+ }
} else {
print '';
print ''.$langs->trans("UseTheFollowingUrlAsRedirectURI").' ';
@@ -213,14 +240,32 @@ foreach ($listinsetup as $key) {
// Api Id
print ' ';
print ''.$langs->trans("OAUTH_ID").' ';
- print ' ';
+ print ' ';
print ' ';
// Api Secret
print '';
print ''.$langs->trans("OAUTH_SECRET").' ';
- print ' ';
+ print ' ';
print ' ';
+
+ // TODO Move this into token generation
+ if ($supported) {
+ if ($keyforsupportedoauth2array == 'OAUTH_OTHER_NAME') {
+ print '';
+ print ''.$langs->trans("Scopes").' ';
+ print '';
+ print ' ';
+ print ' ';
+ } else {
+ print '';
+ print ''.$langs->trans("Scopes").' ';
+ print '';
+ //print ' ';
+ print $supportedoauth2array[$keyforsupportedoauth2array]['defaultscope'];
+ print ' ';
+ }
+ }
}
print '
'."\n";
diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php
index b2830f95743..00daaf01e27 100644
--- a/htdocs/admin/oauthlogintokens.php
+++ b/htdocs/admin/oauthlogintokens.php
@@ -138,11 +138,17 @@ if (GETPOST('error')) {
if ($mode == 'setup' && $user->admin) {
print ''.$langs->trans("OAuthSetupForLogin")." \n";
- //var_dump($list);
+ // Define $listinsetup
foreach ($conf->global as $key => $val) {
if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) {
$provider = preg_replace('/_ID$/', '', $key);
- $listinsetup[] = array($provider.'_NAME', $provider.'_ID', $provider.'_SECRET', 'OAUTH Provider '.str_replace('OAUTH_', '', $provider));
+ $listinsetup[] = array(
+ $provider.'_NAME',
+ $provider.'_ID',
+ $provider.'_SECRET',
+ $provider.'_URLAUTHORIZE', // For custom oauth links
+ $provider.'_SCOPE' // For custom oauth links
+ );
}
}
@@ -165,46 +171,39 @@ if ($mode == 'setup' && $user->admin) {
$OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : ''));
- // Define $shortscope, $urltorenew, $urltodelete, $urltocheckperms
+ $shortscope = $supportedoauth2array[$keyforsupportedoauth2array]['defaultscope'];
+ if (getDolGlobalString($key[4])) {
+ $shortscope = getDolGlobalString($key[4]);
+ }
+ $state = $shortscope; // TODO USe a better state
+
+ // Define $urltorenew, $urltodelete, $urltocheckperms
// TODO Use array $supportedoauth2array
if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') {
// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
// We pass this param list in to 'state' because we need it before and after the redirect.
- $shortscope = 'user,public_repo';
- // Note: github does not accept csrf key inside the state parameter (only know values)
- $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
+ // Note: github does not accept csrf key inside the state parameter (only known values)
+ $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
$urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
$urltocheckperms = 'https://github.com/settings/applications/';
} elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') {
// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
// List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes
// We pass this key list into the param 'state' because we need it before and after the redirect.
- $shortscope = 'userinfo_email,userinfo_profile';
- $shortscope .= ',openid,email,profile'; // For openid connect
- if (!empty($conf->printing->enabled)) {
- $shortscope .= ',cloud_print';
- }
- if (!empty($conf->global->OAUTH_GOOGLE_GSUITE)) {
- $shortscope .= ',admin_directory_user';
- }
- if (!empty($conf->global->OAUTH_GOOGLE_GMAIL)) {
- $shortscope.=',gmail_full';
- }
-
- $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
+ $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
$urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
$urltocheckperms = 'https://security.google.com/settings/security/permissions';
} elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_TEST_NAME') {
- $shortscope = 'none';
-
- $urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
+ $urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
$urltodelete = '';
$urltocheckperms = '';
} elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_LIVE_NAME') {
- $shortscope = 'none';
-
- $urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
+ $urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
+ $urltodelete = '';
+ $urltocheckperms = '';
+ } elseif ($keyforsupportedoauth2array = 'OAUTH_OTHER_NAME') {
+ $urltorenew = $urlwithroot.'/core/modules/oauth/generic_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
$urltodelete = '';
$urltocheckperms = '';
} else {
@@ -212,7 +211,8 @@ if ($mode == 'setup' && $user->admin) {
$urltodelete = '';
$urltocheckperms = '';
}
- $urltorenew .= '&keyforprovider='.$keyforprovider;
+
+ $urltorenew .= '&keyforprovider='.urlencode($keyforprovider);
// Show value of token
$tokenobj = null;
@@ -246,7 +246,7 @@ if ($mode == 'setup' && $user->admin) {
} elseif ($endoflife == $tokenobj::EOL_UNKNOWN) {
$expiredat = $langs->trans("Unknown");
} else {
- $expiredat = dol_print_date($endoflife, "dayhour");
+ $expiredat = dol_print_date($endoflife, "dayhour", 'tzuserrel');
}
}
}
@@ -260,10 +260,16 @@ if ($mode == 'setup' && $user->admin) {
print '';
print '
'."\n";
+ // Api Name
+ $label = $langs->trans($keyforsupportedoauth2array);
print '';
print '';
print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"');
- print $langs->trans($keyforsupportedoauth2array);
+ if ($label == $keyforsupportedoauth2array) {
+ print $supportedoauth2array[$keyforsupportedoauth2array]['name'];
+ } else {
+ print $label;
+ }
if ($keyforprovider) {
print ' ('.$keyforprovider.' )';
} else {
@@ -292,7 +298,8 @@ if ($mode == 'setup' && $user->admin) {
print '';
print ' ';
if (is_object($tokenobj)) {
- print $langs->trans("HasAccessToken");
+ // TODO Read in database to get the date of creation of token
+ print $form->textwithpicto(yn(1), $langs->trans("HasAccessToken").' : ');
} else {
print ''.$langs->trans("NoAccessToken").' ';
}
@@ -305,7 +312,9 @@ if ($mode == 'setup' && $user->admin) {
}
// Request remote token
if ($urltorenew) {
- print ''.$langs->trans('RequestAccess').' ';
+ print ''.$langs->trans('GetAccess').' ';
+ print $form->textwithpicto('', $langs->trans('RequestAccess'));
+ print ' ';
}
// Check remote access
if ($urltocheckperms) {
@@ -378,8 +387,8 @@ if ($mode == 'setup' && $user->admin) {
}
}
-
print '';
+ print ' ';
}
}
diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php
index 763463d6fb8..c55db4ef2a1 100644
--- a/htdocs/barcode/printsheet.php
+++ b/htdocs/barcode/printsheet.php
@@ -203,25 +203,30 @@ if ($action == 'builddoc') {
$forceimgscalewidth = (empty($conf->global->BARCODE_FORCEIMGSCALEWIDTH) ? 1 : $conf->global->BARCODE_FORCEIMGSCALEWIDTH);
$forceimgscaleheight = (empty($conf->global->BARCODE_FORCEIMGSCALEHEIGHT) ? 1 : $conf->global->BARCODE_FORCEIMGSCALEHEIGHT);
- for ($i = 0; $i < $numberofsticker; $i++) {
- $arrayofrecords[] = array(
- 'textleft'=>$textleft,
- 'textheader'=>$textheader,
- 'textfooter'=>$textfooter,
- 'textright'=>$textright,
- 'code'=>$code,
- 'encoding'=>$encoding,
- 'is2d'=>$is2d,
- 'photo'=>$barcodeimage // Photo must be a file that exists with format supported by TCPDF
- );
+ $MAXSTICKERS = 1000;
+ if ($numberofsticker <= $MAXSTICKERS) {
+ for ($i = 0; $i < $numberofsticker; $i++) {
+ $arrayofrecords[] = array(
+ 'textleft'=>$textleft,
+ 'textheader'=>$textheader,
+ 'textfooter'=>$textfooter,
+ 'textright'=>$textright,
+ 'code'=>$code,
+ 'encoding'=>$encoding,
+ 'is2d'=>$is2d,
+ 'photo'=>$barcodeimage // Photo must be a file that exists with format supported by TCPDF
+ );
+ }
+ } else {
+ $mesg = $langs->trans("ErrorQuantityIsLimitedTo", $MAXSTICKERS);
+ $error++;
}
}
$i++;
- $mesg = '';
// Build and output PDF
- if ($mode == 'label') {
+ if (!$error && $mode == 'label') {
if (!count($arrayofrecords)) {
$mesg = $langs->trans("ErrorRecordNotFound");
}
@@ -240,7 +245,7 @@ if ($action == 'builddoc') {
}
}
- if ($result <= 0 || $mesg) {
+ if ($result <= 0 || $mesg || $error) {
if (empty($mesg)) {
$mesg = 'Error '.$result;
}
@@ -272,8 +277,6 @@ print ' ';
print ''.$langs->trans("PageToGenerateBarCodeSheets", $langs->transnoentitiesnoconv("BuildPageToPrint")).' ';
print ' ';
-dol_htmloutput_errors($mesg);
-
//print img_picto('','puce').' '.$langs->trans("PrintsheetForOneBarCode").' ';
//print ' ';
diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php
index fcac14f1337..0a618974024 100644
--- a/htdocs/categories/class/api_categories.class.php
+++ b/htdocs/categories/class/api_categories.class.php
@@ -305,7 +305,8 @@ class Categories extends DolibarrApi
Categorie::TYPE_CUSTOMER,
Categorie::TYPE_SUPPLIER,
Categorie::TYPE_MEMBER,
- Categorie::TYPE_PROJECT
+ Categorie::TYPE_PROJECT,
+ Categorie::TYPE_KNOWLEDGEMANAGEMENT
])) {
throw new RestException(401);
}
@@ -322,6 +323,8 @@ class Categories extends DolibarrApi
throw new RestException(401);
} elseif ($type == Categorie::TYPE_PROJECT && !DolibarrApiAccess::$user->rights->projet->lire) {
throw new RestException(401);
+ } elseif ($type == Categorie::TYPE_KNOWLEDGEMANAGEMENT && !DolibarrApiAccess::$user->rights->knowledgemanagement->knowledgerecord->read) {
+ throw new RestException(401);
}
$categories = $this->category->getListForItem($id, $type, $sortfield, $sortorder, $limit, $page);
diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php
index 8d26b5583d4..b222f70110a 100644
--- a/htdocs/categories/class/categorie.class.php
+++ b/htdocs/categories/class/categorie.class.php
@@ -703,13 +703,14 @@ class Categorie extends CommonObject
$type = $obj->element;
}
+ dol_syslog(get_class($this).'::add_type', LOG_DEBUG);
+
$this->db->begin();
$sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie_".(empty($this->MAP_CAT_TABLE[$type]) ? $type : $this->MAP_CAT_TABLE[$type]);
$sql .= " (fk_categorie, fk_".(empty($this->MAP_CAT_FK[$type]) ? $type : $this->MAP_CAT_FK[$type]).")";
$sql .= " VALUES (".((int) $this->id).", ".((int) $obj->id).")";
- dol_syslog(get_class($this).'::add_type', LOG_DEBUG);
if ($this->db->query($sql)) {
if (!empty($conf->global->CATEGORIE_RECURSIV_ADD)) {
$sql = 'SELECT fk_parent FROM '.MAIN_DB_PREFIX.'categorie';
diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php
index 5450127bff3..5405b33d994 100644
--- a/htdocs/categories/viewcat.php
+++ b/htdocs/categories/viewcat.php
@@ -1030,7 +1030,7 @@ if ($type == Categorie::TYPE_PROJECT) {
}
// List of users
-if ($type == Categorie::TYPE_USER) {
+if ($type == Categorie::TYPE_USER && $user->hasRight("user", "user", "read")) {
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
$users = $object->getObjectsInCateg($type);
@@ -1099,6 +1099,9 @@ if ($type == Categorie::TYPE_USER) {
print ''."\n";
}
+} else {
+ print_barre_liste($langs->trans("Users"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'user');
+ accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0);
}
diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php
index ed25d89db67..6dd6cd5663b 100644
--- a/htdocs/comm/action/card.php
+++ b/htdocs/comm/action/card.php
@@ -538,7 +538,7 @@ if (empty($reshook) && $action == 'add') {
$error++;
}
// End date
- $repeateventlimitdate = dol_mktime('23', '59', '59', GETPOSTISSET("limitmonth", 'int') ? GETPOST("limitmonth", 'int') : 01, GETPOSTISSET("limitday", 'int') ? GETPOST("limitday", 'int') : 01, GETPOSTISSET("limityear", 'int') && GETPOST("limityear", 'int') < 2100 ? GETPOST("limityear", 'int') : 2100, $tzforfullday ? $tzforfullday : 'tzuser');
+ $repeateventlimitdate = dol_mktime('23', '59', '59', GETPOSTISSET("limitmonth") ? GETPOST("limitmonth", 'int') : 01, GETPOSTISSET("limitday", 'int') ? GETPOST("limitday", 'int') : 01, GETPOSTISSET("limityear", 'int') && GETPOST("limityear", 'int') < 2100 ? GETPOST("limityear", 'int') : 2100, $tzforfullday ? $tzforfullday : 'tzuser');
// Set date of end of event
$deltatime = num_between_day($object->datep, $datep);
$datef = dol_time_plus_duree($datef, $deltatime, 'd');
@@ -677,7 +677,7 @@ if (empty($reshook) && $action == 'update') {
$object->fetch($id);
$object->fetch_optionals();
$object->fetch_userassigned();
- $object->oldcopy = clone $object;
+ $object->oldcopy = dol_clone($object);
// Clean parameters
if ($fulldayevent) {
@@ -927,7 +927,7 @@ if (empty($reshook) && $action == 'confirm_delete' && GETPOST("confirm") == 'yes
$object->fetch($id);
$object->fetch_optionals();
$object->fetch_userassigned();
- $object->oldcopy = clone $object;
+ $object->oldcopy = dol_clone($object);
if ($user->rights->agenda->myactions->delete
|| $user->rights->agenda->allactions->delete) {
diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php
index 2afad30c454..c60f10be857 100644
--- a/htdocs/comm/action/index.php
+++ b/htdocs/comm/action/index.php
@@ -212,7 +212,7 @@ if (GETPOST("viewperuser", 'alpha') || $mode == 'show_peruser') {
$event->fetch($actionid);
$event->fetch_optionals();
$event->fetch_userassigned();
- $event->oldcopy = clone $event;
+ $event->oldcopy = dol_clone($event);
$result = $event->delete();
}
diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php
index 85eb355f2b6..d21b20bbfaf 100644
--- a/htdocs/comm/action/pertype.php
+++ b/htdocs/comm/action/pertype.php
@@ -189,7 +189,7 @@ if ($action == 'delete_action' && $user->rights->agenda->delete) {
$event->fetch($actionid);
$event->fetch_optionals();
$event->fetch_userassigned();
- $event->oldcopy = clone $event;
+ $event->oldcopy = dol_clone($event);
$result = $event->delete();
}
diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php
index 87def7240f5..b30ef8f7ba9 100644
--- a/htdocs/comm/action/peruser.php
+++ b/htdocs/comm/action/peruser.php
@@ -196,7 +196,7 @@ if ($action == 'delete_action' && $user->rights->agenda->delete) {
$event->fetch($actionid);
$event->fetch_optionals();
$event->fetch_userassigned();
- $event->oldcopy = clone $event;
+ $event->oldcopy = dol_clone($event);
$result = $event->delete();
}
diff --git a/htdocs/comm/multiprix.php b/htdocs/comm/multiprix.php
index 8da9a17ebb2..0e582946df9 100644
--- a/htdocs/comm/multiprix.php
+++ b/htdocs/comm/multiprix.php
@@ -75,7 +75,7 @@ if ($_socid > 0) {
// We load data of thirdparty
$objsoc = new Societe($db);
$objsoc->id = $_socid;
- $objsoc->fetch($_socid, $to);
+ $objsoc->fetch($_socid);
$head = societe_prepare_head($objsoc);
@@ -141,7 +141,6 @@ if ($_socid > 0) {
$resql = $db->query($sql);
if ($resql) {
print '';
- $tag = !$tag;
print '';
print ''.$langs->trans("Date").' ';
print ''.$langs->trans("PriceLevel").' ';
diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php
index f1a92d032cf..0521d203331 100644
--- a/htdocs/comm/propal/card.php
+++ b/htdocs/comm/propal/card.php
@@ -112,9 +112,9 @@ if ($id > 0 || !empty($ref)) {
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('propalcard', 'globalcard'));
-$usercanread = $user->rights->propal->lire;
-$usercancreate = $user->rights->propal->creer;
-$usercandelete = $user->rights->propal->supprimer;
+$usercanread = $user->hasRight("propal", "lire");
+$usercancreate = $user->hasRight("propal", "creer");
+$usercandelete = $user->hasRight("propal", "supprimer");
$usercanclose = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->close)));
$usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->validate)));
@@ -1851,7 +1851,7 @@ if ($action == 'create') {
// Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
$objectsrc->remise_absolue = $remise_absolue; // deprecated
$objectsrc->remise_percent = $remise_percent;
- $objectsrc->update_price(1, - 1, 1);
+ $objectsrc->update_price(1, 'auto', 1);
}
print "\n";
diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php
index aa26e7be794..43c49bdc8a2 100644
--- a/htdocs/commande/card.php
+++ b/htdocs/commande/card.php
@@ -108,9 +108,9 @@ $extrafields->fetch_name_optionals_label($object->table_element);
// Load object
include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
-$usercanread = $user->hasRight('commande', 'lire');
-$usercancreate = $user->hasRight('commande', 'creer');
-$usercandelete = $user->hasRight('commande', 'supprimer');
+$usercanread = $user->hasRight("commande", "lire");
+$usercancreate = $user->hasRight("commande", "creer");
+$usercandelete = $user->hasRight("commande", "supprimer");
// Advanced permissions
$usercanclose = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($usercancreate)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->hasRight('commande', 'order_advance', 'close'))));
diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php
index 511d75a12c8..f24afc0700b 100644
--- a/htdocs/compta/bank/bankentries_list.php
+++ b/htdocs/compta/bank/bankentries_list.php
@@ -235,8 +235,12 @@ if (empty($reshook)) {
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
}
+$rowids = GETPOST('rowid', 'array');
+
// Conciliation
-if ((GETPOST('confirm_savestatement', 'alpha') || GETPOST('confirm_reconcile', 'alpha')) && !empty($user->rights->banque->consolidate)
+if ((GETPOST('confirm_savestatement', 'alpha') || GETPOST('confirm_reconcile', 'alpha'))
+ && (GETPOST("num_releve", "alpha") || !empty($rowids))
+ && !empty($user->rights->banque->consolidate)
&& (!GETPOSTISSET('pageplusone') || (GETPOST('pageplusone') == GETPOST('pageplusoneold')))) {
$error = 0;
diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php
index 2751947c023..3dfe18a3581 100644
--- a/htdocs/compta/bank/card.php
+++ b/htdocs/compta/bank/card.php
@@ -846,6 +846,9 @@ if ($action == 'create') {
$object = new Account($db);
$object->fetch(GETPOST('id', 'int'));
+ $title = $object->ref." - ".$langs->trans("Card");
+ llxHeader("", $title, $help_url);
+
print load_fiche_titre($langs->trans("EditFinancialAccount"), '', 'bank_account');
if ($conf->use_javascript_ajax) {
@@ -1014,7 +1017,7 @@ if ($action == 'create') {
$tdextra = ' class="fieldrequired titlefieldcreate"';
}
- print ' '.$langs->trans("AccountancyCode").' ';
+ print ''.$langs->trans("AccountancyCode").' ';
print '';
if (!empty($conf->accounting->enabled)) {
print $formaccounting->select_account($object->account_number, 'account_number', 1, '', 1, 1);
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index 59345604d1d..0c53be74ef7 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -128,11 +128,11 @@ if ($id > 0 || !empty($ref)) {
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('invoicecard', 'globalcard'));
-$usercanread = $user->rights->facture->lire;
-$usercancreate = $user->rights->facture->creer;
-$usercanissuepayment = $user->rights->facture->paiement;
-$usercandelete = $user->rights->facture->supprimer;
-$usercancreatecontract = $user->rights->contrat->creer;
+$usercanread = $user->hasRight("facture", "lire");
+$usercancreate = $user->hasRight("facture", "creer");
+$usercanissuepayment = $user->hasRight("facture", "paiement");
+$usercandelete = $user->hasRight("facture", "supprimer");
+$usercancreatecontract = $user->hasRight("contrat", "creer");
$usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->facture->invoice_advance->validate)));
$usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->facture->invoice_advance->send)));
$usercanreopen = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->facture->invoice_advance->reopen)));
@@ -3785,7 +3785,7 @@ if ($action == 'create') {
// Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
$objectsrc->remise_absolue = $remise_absolue;
$objectsrc->remise_percent = $remise_percent;
- $objectsrc->update_price(1, - 1, 1);
+ $objectsrc->update_price(1, 'auto', 1);
}
print "\n\n";
diff --git a/htdocs/compta/paiement/cheque/card.php b/htdocs/compta/paiement/cheque/card.php
index 8c859e6e689..f41ecd820ad 100644
--- a/htdocs/compta/paiement/cheque/card.php
+++ b/htdocs/compta/paiement/cheque/card.php
@@ -59,8 +59,15 @@ $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$offset = $limit * $page;
$upload_dir = $conf->bank->multidir_output[$object->entity ? $object->entity : $conf->entity]."/checkdeposits";
-
-$filterdate = dol_mktime(0, 0, 0, GETPOST('fdmonth'), GETPOST('fdday'), GETPOST('fdyear'));
+// filter by dates from / to
+$search_date_start_day = GETPOST('search_date_start_day', 'int');
+$search_date_start_month = GETPOST('search_date_start_month', 'int');
+$search_date_start_year = GETPOST('search_date_start_year', 'int');
+$search_date_end_day = GETPOST('search_date_end_day', 'int');
+$search_date_end_month = GETPOST('search_date_end_month', 'int');
+$search_date_end_year = GETPOST('search_date_end_year', 'int');
+$search_date_start = dol_mktime(0, 0, 0, $search_date_start_month, $search_date_start_day, $search_date_start_year);
+$search_date_end = dol_mktime(23, 59, 59, $search_date_end_month, $search_date_end_day, $search_date_end_year);
$filteraccountid = GETPOST('accountid', 'int');
// Security check
@@ -265,7 +272,15 @@ if ($action == 'builddoc' && $user->rights->banque->cheque) {
*/
if (GETPOST('removefilter')) {
- $filterdate = '';
+ // filter by dates from / to
+ $search_date_start_day = '';
+ $search_date_start_month = '';
+ $search_date_start_year = '';
+ $search_date_end_day = '';
+ $search_date_end_month = '';
+ $search_date_end_year = '';
+ $search_date_start = '';
+ $search_date_end = '';
$filteraccountid = 0;
}
@@ -352,7 +367,13 @@ if ($action == 'new') {
//print ' '.$langs->trans('Date').' '.dol_print_date($now,'day').' ';
// Filter
print ''.$langs->trans("DateChequeReceived").' ';
- print $form->selectDate($filterdate, 'fd', 0, 0, 1, '', 1, 1);
+ // filter by dates from / to
+ print '';
+ print $form->selectDate($search_date_start, 'search_date_start_', 0, 0, 1, '', 1, 1, 0, '', '', '', '', 1, '', $langs->trans('From'));
+ print '
';
+ print '';
+ print $form->selectDate($search_date_end, 'search_date_end_', 0, 0, 1, '', 1, 1, 0, '', '', '', '', 1, '', $langs->trans('to'));
+ print '
';
print ' ';
print ''.$langs->trans("BankAccount").' ';
$form->select_comptes($filteraccountid, 'accountid', 0, 'courant <> 2', 1);
@@ -363,7 +384,7 @@ if ($action == 'new') {
print '';
print '
';
- if ($filterdate || $filteraccountid > 0) {
+ if ($search_date_start || $search_date_end || $filteraccountid > 0) {
print ' ';
print '
';
}
@@ -382,8 +403,11 @@ if ($action == 'new') {
$sql .= " AND ba.entity IN (".getEntity('bank_account').")";
$sql .= " AND b.fk_bordereau = 0";
$sql .= " AND b.amount > 0";
- if ($filterdate) {
- $sql .= " AND b.dateo = '".$db->idate($filterdate)."'";
+ if ($search_date_start) {
+ $sql .= " AND b.dateo >= '".$db->idate($search_date_start)."'";
+ }
+ if ($search_date_end) {
+ $sql .= " AND b.dateo <= '".$db->idate($search_date_end)."'";
}
if ($filteraccountid > 0) {
$sql .= " AND ba.rowid = ".((int) $filteraccountid);
diff --git a/htdocs/compta/paiement_charge.php b/htdocs/compta/paiement_charge.php
index ba62c36b0fa..99940ecffcb 100644
--- a/htdocs/compta/paiement_charge.php
+++ b/htdocs/compta/paiement_charge.php
@@ -169,13 +169,8 @@ if ($action == 'create') {
}
print load_fiche_titre($langs->trans("DoPayment"));
- print "
\n";
- if ($mesg) {
- print "
$mesg
";
- }
-
- print '
';
// Severity
print ''.$langs->trans("TicketSeverity").' ';
- $this->selectSeveritiesTickets((GETPOST('severity_code') ? GETPOST('severity_code') : $this->severity_code), 'severity_code', '', 2, 0);
+ $this->selectSeveritiesTickets((GETPOST('severity_code') ? GETPOST('severity_code') : $this->severity_code), 'severity_code', '', 2, 1);
print ' ';
// Subject
@@ -735,6 +735,7 @@ class FormTicket
}
print '>';
+
$value = ' ';
if ($format == 0) {
$value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']);
@@ -746,7 +747,7 @@ class FormTicket
$value = $arraytypes['code'];
}
- print $value;
+ print $value ? $value : ' ';
print '';
}
}
@@ -841,6 +842,7 @@ class FormTicket
print '>';
+ $value = '';
if ($format == 0) {
$value = ($maxlength ? dol_trunc($label, $maxlength) : $label);
}
@@ -1174,6 +1176,8 @@ class FormTicket
}
print '>';
+
+ $value = '';
if ($format == 0) {
$value = ($maxlength ? dol_trunc($arrayseverities['label'], $maxlength) : $arrayseverities['label']);
}
diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php
index 1f5a48a517d..06ada5c4911 100644
--- a/htdocs/core/class/smtps.class.php
+++ b/htdocs/core/class/smtps.class.php
@@ -68,6 +68,11 @@ class SMTPs
*/
private $_smtpsPW = null;
+ /**
+ * Token in case we use OAUTH2
+ */
+ private $_smtpsToken = null;
+
/**
* Who sent the Message
* This can be defined via a INI file or via a setter method
@@ -565,13 +570,13 @@ class SMTPs
}
// Default authentication method is LOGIN
- if (empty($conf->global->MAIL_SMTP_AUTH_TYPE)) {
- $conf->global->MAIL_SMTP_AUTH_TYPE = 'LOGIN';
+ if (empty($conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE)) {
+ $conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE = 'LOGIN';
}
// Send Authentication to Server
// Check for errors along the way
- switch ($conf->global->MAIL_SMTP_AUTH_TYPE) {
+ switch ($conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE) {
case 'NONE':
// Do not send the 'AUTH type' message. For test purpose, if you don't need authentication, it is better to not enter login/pass into setup.
$_retVal = true;
@@ -583,9 +588,10 @@ class SMTPs
break;
case 'XOAUTH2':
// "user=$email\1auth=Bearer $token\1\1"
- $token = 'xxx';
- $xxxx = "user=".$this->_smtpsID."\1auth=Bearer ".$token."\1\1";
- $_retVal = $this->socket_send_str('AUTH XOAUTH2 '.base64_encode($xxxx), '235');
+ $user = $this->_smtpsID;
+ $token = $this->_smtpsToken;
+ $initRes = "user=".$user."\001auth=Bearer ".$token."\001\001";
+ $_retVal = $this->socket_send_str('AUTH XOAUTH2 '.base64_encode($initRes), '235');
if (!$_retVal) {
$this->_setErr(130, 'Error when asking for AUTH XOAUTH2');
}
@@ -631,7 +637,7 @@ class SMTPs
// Connect to Server
if ($this->socket = $this->_server_connect()) {
// If a User ID *and* a password is given, assume Authentication is desired
- if (!empty($this->_smtpsID) && !empty($this->_smtpsPW)) {
+ if (!empty($this->_smtpsID) && (!empty($this->_smtpsPW) || !empty($this->_smtpsToken))) {
// Send the RFC2554 specified EHLO.
$_retVal = $this->_server_authenticate();
} else {
@@ -923,6 +929,27 @@ class SMTPs
return $this->_smtpsPW;
}
+ /**
+ * User token for OAUTH2
+ *
+ * @param string $_strToken User token
+ * @return void
+ */
+ public function setToken($_strToken)
+ {
+ $this->_smtpsToken = $_strToken;
+ }
+
+ /**
+ * Retrieves the User token for OAUTH2
+ *
+ * @return string User token for OAUTH2
+ */
+ public function getToken()
+ {
+ return $this->_smtpsToken;
+ }
+
/**
* Character set used for current message
* Character set is defaulted to 'iso-8859-1';
@@ -1866,7 +1893,7 @@ class SMTPs
}
if (!(substr($server_response, 0, 3) == $response)) {
- $this->_setErr(120, "Ran into problems sending Mail.\r\nResponse: $server_response");
+ $this->_setErr(120, "Ran into problems sending Mail.\r\nResponse:".$server_response);
$_retVal = false;
}
diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php
index 255cdb2fb67..29db15e0a0b 100644
--- a/htdocs/core/class/translate.class.php
+++ b/htdocs/core/class/translate.class.php
@@ -640,6 +640,7 @@ class Translate
try {
$str = sprintf($str, $param1, $param2, $param3, $param4); // Replace %s and %d except for FormatXXX strings.
} catch (Exception $e) {
+ // No exception managed
}
}
diff --git a/htdocs/core/class/utils_diff.class.php b/htdocs/core/class/utils_diff.class.php
index 9abc1d899fe..2925bffc3b6 100644
--- a/htdocs/core/class/utils_diff.class.php
+++ b/htdocs/core/class/utils_diff.class.php
@@ -247,6 +247,7 @@ class Diff
$html = '';
// loop over the lines in the diff
+ $element = 'unknown';
foreach ($diff as $line) {
// extend the HTML with the line
switch ($line[1]) {
@@ -260,10 +261,7 @@ class Diff
$element = 'ins';
break;
}
- $html .=
- '<'.$element.'>'
- . htmlspecialchars($line[0])
- . ''.$element.'>';
+ $html .= '<'.$element.'>'.dol_escape_htmltag($line[0]).''.$element.'>';
// extend the HTML with the separator
$html .= $separator;
@@ -286,6 +284,8 @@ class Diff
// initialise the HTML
$html = $indentation."\n";
+ $rightCell = $leftCell = '';
+
// loop over the lines in the diff
$index = 0;
$nbdiff = count($diff);
diff --git a/htdocs/core/filemanagerdol/browser/default/browser.php b/htdocs/core/filemanagerdol/browser/default/browser.php
index b5bce100d39..0c1b29d12b2 100644
--- a/htdocs/core/filemanagerdol/browser/default/browser.php
+++ b/htdocs/core/filemanagerdol/browser/default/browser.php
@@ -21,10 +21,12 @@
//define('NOTOKENRENEWAL',1); // Disables token renewal
//require '../../../../main.inc.php';
-require '../../connectors/php/config.php'; // This include the define('NOTOKENRENEWAL',1) and the require main.in.php
+require '../../connectors/php/config.inc.php'; // This include the define('NOTOKENRENEWAL',1) and the require main.in.php
global $Config;
+top_httphead();
+
?>
diff --git a/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php b/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php
index c66187ee433..949307c0624 100644
--- a/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php
+++ b/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php
@@ -23,6 +23,8 @@ define('NOTOKENRENEWAL', 1); // Disables token renewal
require '../../../../main.inc.php';
+top_httphead();
+
?>
'."\n";
print '';
+ // Ref
print ''.$langs->trans("ToConsume").' ';
$preselected = (GETPOSTISSET('qty-'.$line->id.'-'.$i) ? GETPOST('qty-'.$line->id.'-'.$i) : max(0, $line->qty - $alreadyconsumed));
if ($action == 'consumeorproduce' && !GETPOSTISSET('qty-'.$line->id.'-'.$i)) {
@@ -1044,12 +1048,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
$preselected = (GETPOSTISSET('batch-'.$line->id.'-'.$i) ? GETPOST('batch-'.$line->id.'-'.$i) : '');
print ' ';
print $formproduct->selectLotDataList('batch-'.$line->id.'-'.$i, 0, $line->fk_product, '', '');
- }
- print '';
- print '';
- if ($tmpproduct->status_batch) {
+
$type = 'batch';
- print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine('.$line->id.', \''.$type.'\', \'qtymissingconsume\')"');
+ print ' '.img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine('.((int) $line->id).', \''.dol_escape_js($type).'\', \'qtymissingconsume\')"');
}
print ' ';
}
@@ -1094,10 +1095,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
$newcardbutton = '';
$url = $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addproduceline&token='.newToken();
- $permissiontoaddaproductline = $object->status != $object::STATUS_PRODUCED && $object->status != $object::STATUS_CANCELED && $action != 'consumeorproduce' && $action != 'consumeandproduceall';
+ $permissiontoaddaproductline = $object->status != $object::STATUS_PRODUCED && $object->status != $object::STATUS_CANCELED;
$parameters = array('morecss'=>'reposition');
- if ($nblinetoproduce == 0 || $object->mrptype == 1) {
- $newcardbutton = dolGetButtonTitle($langs->trans('AddNewProduceLines'), '', 'fa fa-plus-circle size15x', $url, '', $permissiontoaddaproductline, $parameters);
+ if ($action != 'consumeorproduce' && $action != 'consumeandproduceall') {
+ if ($nblinetoproduce == 0 || $object->mrptype == 1) {
+ $newcardbutton = dolGetButtonTitle($langs->trans('AddNewProduceLines'), '', 'fa fa-plus-circle size15x', $url, '', $permissiontoaddaproductline, $parameters);
+ }
}
print load_fiche_titre($langs->trans('Production'), $newcardbutton, '', 0, '', '');
@@ -1196,12 +1199,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print ''.$line->qty.' ';
if ($permissiontoupdatecost) {
// Defined $manufacturingcost
- $manufacturingcost = $bomcost;
- if (empty($manufacturingcost)) {
- $manufacturingcost = price2num($tmpproduct->cost_price, 'MU');
- }
- if (empty($manufacturingcost)) {
- $manufacturingcost = price2num($tmpproduct->pmp, 'MU');
+ $manufacturingcost = 0;
+ if ($object->mrptype == 0) { // If MO is a "Manufacture" type (and not "Disassemble"
+ $manufacturingcost = $bomcost;
+ if (empty($manufacturingcost)) {
+ $manufacturingcost = price2num($tmpproduct->cost_price, 'MU');
+ }
+ if (empty($manufacturingcost)) {
+ $manufacturingcost = price2num($tmpproduct->pmp, 'MU');
+ }
}
print '';
@@ -1300,19 +1306,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print ' ';
if ($permissiontoupdatecost) {
// Defined $manufacturingcost
- $manufacturingcost = $bomcost;
- if (empty($manufacturingcost)) {
- $manufacturingcost = price2num($tmpproduct->cost_price, 'MU');
- }
- if (empty($manufacturingcost)) {
- $manufacturingcost = price2num($tmpproduct->pmp, 'MU');
+ $manufacturingcost = 0;
+ if ($object->mrptype == 0) { // If MO is a "Manufacture" type (and not "Disassemble"
+ $manufacturingcost = $bomcost;
+ if (empty($manufacturingcost)) {
+ $manufacturingcost = price2num($tmpproduct->cost_price, 'MU');
+ }
+ if (empty($manufacturingcost)) {
+ $manufacturingcost = price2num($tmpproduct->pmp, 'MU');
+ }
}
if ($tmpproduct->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
- $preselected = (GETPOSTISSET('pricetoproduce-'.$line->id.'-'.$i) ? GETPOST('pricetoproduce-'.$line->id.'-'.$i) : price($manufacturingcost));
+ $preselected = (GETPOSTISSET('pricetoproduce-'.$line->id.'-'.$i) ? GETPOST('pricetoproduce-'.$line->id.'-'.$i) : ($manufacturingcost ? price($manufacturingcost) : ''));
print ' ';
} else {
- print ' ';
+ print ' ';
}
}
print ' ';
diff --git a/htdocs/mrp/tpl/originproductline.tpl.php b/htdocs/mrp/tpl/originproductline.tpl.php
index e641bd142fc..7e0468119bd 100644
--- a/htdocs/mrp/tpl/originproductline.tpl.php
+++ b/htdocs/mrp/tpl/originproductline.tpl.php
@@ -44,6 +44,7 @@ $res = $tmpbom->fetch($line->fk_bom_child);
tpl['strike']) ? '' : ' strikefordisabled').'">';
+// Ref or label
print '';
if ($res) {
print $tmpproduct->getNomUrl(1);
@@ -58,7 +59,7 @@ if ($res) {
print $this->tpl['label'];
}
print ' ';
-//print ''.$this->tpl['label'].' ';
+// Qty
print ''.$this->tpl['qty'].(($this->tpl['efficiency'] > 0 && $this->tpl['efficiency'] < 1) ? ' / '.$form->textwithpicto($this->tpl['efficiency'], $langs->trans("ValueOfMeansLoss")).' = '.$qtytoconsumeforline : '').' ';
print ''.(empty($this->tpl['stock']) ? 0 : price2num($this->tpl['stock'], 'MS'));
if ($this->tpl['seuil_stock_alerte'] != '' && ($this->tpl['stock'] < $this->tpl['seuil_stock_alerte'])) {
@@ -78,18 +79,19 @@ $selected = 1;
if (!empty($selectedLines) && !in_array($this->tpl['id'], $selectedLines)) {
$selected = 0;
}
-print ' ';
-//print ' ';
-print ' ';
-if ($tmpbom->id) {
+if ($tmpbom->id > 0) {
print '';
print ' ';
print ' ';
} else {
- print ' ';
+ print ' ';
}
+//print '';
+//print ' ';
+//print ' ';
+
print ' '."\n";
// Select of all the sub-BOM lines
diff --git a/htdocs/product/card.php b/htdocs/product/card.php
index 1681ef45387..9137a3b7c10 100644
--- a/htdocs/product/card.php
+++ b/htdocs/product/card.php
@@ -16,7 +16,7 @@
* Copyright (C) 2016-2022 Charlene Benke
* Copyright (C) 2016 Meziane Sof
* Copyright (C) 2017 Josep Lluís Amador
- * Copyright (C) 2019-2021 Frédéric France
+ * Copyright (C) 2019-2022 Frédéric France
* Copyright (C) 2019-2020 Thibault FOUCART
* Copyright (C) 2020 Pierre Ardoin
*
@@ -1973,7 +1973,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
print ''.$langs->trans("Description").' ';
// We use dolibarr_details as type of DolEditor here, because we must not accept images as description is included into PDF and not accepted by TCPDF.
- $doleditor = new DolEditor('desc', $object->description, '', 160, 'dolibarr_details', '', false, true, getDolGlobalInt('FCKEDITOR_ENABLE_PRODUCTDESC'), ROWS_4, '90%');
+ $doleditor = new DolEditor('desc', GETPOSTISSET('desc') ? GETPOST('desc', 'restricthtml') : $object->description, '', 160, 'dolibarr_details', '', false, true, getDolGlobalInt('FCKEDITOR_ENABLE_PRODUCTDESC'), ROWS_4, '90%');
$doleditor->Create();
print " ";
@@ -1983,7 +1983,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
if (empty($conf->global->PRODUCT_DISABLE_PUBLIC_URL)) {
print ''.$langs->trans("PublicUrl").' ';
print img_picto('', 'globe', 'class="pictofixedwidth"');
- print ' ';
+ print ' ';
print ' ';
}
diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php
index 2566ca24919..e34b270562e 100644
--- a/htdocs/product/class/api_products.class.php
+++ b/htdocs/product/class/api_products.class.php
@@ -253,7 +253,7 @@ class Products extends DolibarrApi
if (!$ids_only) {
$product_static = new Product($this->db);
if ($product_static->fetch($obj->rowid)) {
- if ($includestockdata && DolibarrApiAccess::$user->rights->stock->lire) {
+ if (!empty($includestockdata) && DolibarrApiAccess::$user->rights->stock->lire) {
$product_static->load_stock();
if (is_array($product_static->stock_warehouse)) {
@@ -1644,10 +1644,10 @@ class Products extends DolibarrApi
$combinations[$key]->attributes = $prodc2vp->fetchByFkCombination((int) $combination->id);
$combinations[$key] = $this->_cleanObjectDatas($combinations[$key]);
- if ($includestock==1 && DolibarrApiAccess::$user->rights->stock->lire) {
+ if (!empty($includestock) && DolibarrApiAccess::$user->rights->stock->lire) {
$productModel = new Product($this->db);
$productModel->fetch((int) $combination->fk_product_child);
- $productModel->load_stock();
+ $productModel->load_stock($includestock);
$combinations[$key]->stock_warehouse = $this->_cleanObjectDatas($productModel)->stock_warehouse;
}
}
@@ -2040,8 +2040,8 @@ class Products extends DolibarrApi
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
- if ($includestockdata && DolibarrApiAccess::$user->rights->stock->lire) {
- $this->product->load_stock();
+ if (!empty($includestockdata) && DolibarrApiAccess::$user->rights->stock->lire) {
+ $this->product->load_stock($includestockdata);
if (is_array($this->product->stock_warehouse)) {
foreach ($this->product->stock_warehouse as $keytmp => $valtmp) {
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index 6c249e6b3bd..28ddb32624b 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -1051,9 +1051,7 @@ class Product extends CommonObject
if ($result >= 0) {
if (empty($this->oldcopy)) {
- $org = new self($this->db);
- $org->fetch($this->id);
- $this->oldcopy = $org;
+ $this->oldcopy = dol_clone($this);
}
// Test if batch management is activated on existing product
@@ -3038,12 +3036,13 @@ class Product extends CommonObject
/**
* Charge tableau des stats commande fournisseur pour le produit/service
*
- * @param int $socid Id societe pour filtrer sur une societe
- * @param string $filtrestatut Id des statuts pour filtrer sur des statuts
- * @param int $forVirtualStock Ignore rights filter for virtual stock calculation.
- * @return int Array of stats in $this->stats_commande_fournisseur, <0 if ko or >0 if ok
+ * @param int $socid Id societe pour filtrer sur une societe
+ * @param string $filtrestatut Id des statuts pour filtrer sur des statuts
+ * @param int $forVirtualStock Ignore rights filter for virtual stock calculation.
+ * @param int $dateofvirtualstock Date of virtual stock
+ * @return int Array of stats in $this->stats_commande_fournisseur, <0 if ko or >0 if ok
*/
- public function load_stats_commande_fournisseur($socid = 0, $filtrestatut = '', $forVirtualStock = 0)
+ public function load_stats_commande_fournisseur($socid = 0, $filtrestatut = '', $forVirtualStock = 0, $dateofvirtualstock = null)
{
// phpcs:enable
global $conf, $user, $hookmanager, $action;
@@ -3069,6 +3068,9 @@ class Product extends CommonObject
if ($filtrestatut != '') {
$sql .= " AND c.fk_statut in (".$this->db->sanitize($filtrestatut).")"; // Peut valoir 0
}
+ if (!empty($dateofvirtualstock)) {
+ $sql .= " AND c.date_livraison <= '".$this->db->idate($dateofvirtualstock)."'";
+ }
$result = $this->db->query($sql);
if ($result) {
@@ -3181,12 +3183,13 @@ class Product extends CommonObject
/**
* Charge tableau des stats réception fournisseur pour le produit/service
*
- * @param int $socid Id societe pour filtrer sur une societe
- * @param string $filtrestatut Id statut pour filtrer sur un statut
- * @param int $forVirtualStock Ignore rights filter for virtual stock calculation.
+ * @param int $socid Id societe pour filtrer sur une societe
+ * @param string $filtrestatut Id statut pour filtrer sur un statut
+ * @param int $forVirtualStock Ignore rights filter for virtual stock calculation.
+ * @param int $dateofvirtualstock Date of virtual stock
* @return int Array of stats in $this->stats_reception, <0 if ko or >0 if ok
*/
- public function load_stats_reception($socid = 0, $filtrestatut = '', $forVirtualStock = 0)
+ public function load_stats_reception($socid = 0, $filtrestatut = '', $forVirtualStock = 0, $dateofvirtualstock = null)
{
// phpcs:enable
global $conf, $user, $hookmanager, $action;
@@ -3212,6 +3215,9 @@ class Product extends CommonObject
if ($filtrestatut <> '') {
$sql .= " AND cf.fk_statut IN (".$this->db->sanitize($filtrestatut).")";
}
+ if (!empty($dateofvirtualstock)) {
+ $sql .= " AND fd.datec <= '".$this->db->idate($dateofvirtualstock)."'";
+ }
$result = $this->db->query($sql);
if ($result) {
@@ -3238,12 +3244,13 @@ class Product extends CommonObject
/**
* Charge tableau des stats production pour le produit/service
*
- * @param int $socid Id societe pour filtrer sur une societe
- * @param string $filtrestatut Id statut pour filtrer sur un statut
- * @param int $forVirtualStock Ignore rights filter for virtual stock calculation.
+ * @param int $socid Id societe pour filtrer sur une societe
+ * @param string $filtrestatut Id statut pour filtrer sur un statut
+ * @param int $forVirtualStock Ignore rights filter for virtual stock calculation.
+ * @param int $dateofvirtualstock Date of virtual stock
* @return integer Array of stats in $this->stats_mrptoproduce (nb=nb of order, qty=qty ordered), <0 if ko or >0 if ok
*/
- public function load_stats_inproduction($socid = 0, $filtrestatut = '', $forVirtualStock = 0)
+ public function load_stats_inproduction($socid = 0, $filtrestatut = '', $forVirtualStock = 0, $dateofvirtualstock = null)
{
// phpcs:enable
global $conf, $user, $hookmanager, $action;
@@ -3268,6 +3275,9 @@ class Product extends CommonObject
if ($filtrestatut <> '') {
$sql .= " AND m.status IN (".$this->db->sanitize($filtrestatut).")";
}
+ if (!empty($dateofvirtualstock)) {
+ $sql .= " AND m.date_valid <= '".$this->db->idate($dateofvirtualstock)."'"; // better date to code ? end of production ?
+ }
$sql .= " GROUP BY role";
$this->stats_mrptoconsume['customers'] = 0;
@@ -5037,7 +5047,7 @@ class Product extends CommonObject
$result .= (img_object(($notooltip ? '' : $label), 'service', ($notooltip ? 'class="paddingright"' : 'class="paddingright classfortooltip"'), 0, 0, $notooltip ? 0 : 1));
}
}
- $result .= $newref;
+ $result .= dol_escape_htmltag($newref);
$result .= $linkend;
if ($withpicto != 2) {
$result .= (($add_label && $this->label) ? $sep.dol_trunc($this->label, ($add_label > 1 ? $add_label : 0)) : '');
@@ -5346,10 +5356,11 @@ class Product extends CommonObject
* @param string $option '' = Load all stock info, also from closed and internal warehouses, 'nobatch', 'novirtual'
* You can also filter on 'warehouseclosed', 'warehouseopen', 'warehouseinternal'
* @param int $includedraftpoforvirtual Include draft status of PO for virtual stock calculation
+ * @param int $dateofvirtualstock Date of virtual stock
* @return int < 0 if KO, > 0 if OK
* @see load_virtual_stock(), loadBatchInfo()
*/
- public function load_stock($option = '', $includedraftpoforvirtual = null)
+ public function load_stock($option = '', $includedraftpoforvirtual = null, $dateofvirtualstock = null)
{
// phpcs:enable
global $conf;
@@ -5407,7 +5418,7 @@ class Product extends CommonObject
$this->db->free($result);
if (!preg_match('/novirtual/', $option)) {
- $this->load_virtual_stock($includedraftpoforvirtual); // This also load all arrays stats_xxx...
+ $this->load_virtual_stock($includedraftpoforvirtual, $dateofvirtualstock); // This also load all arrays stats_xxx...
}
return 1;
@@ -5424,10 +5435,11 @@ class Product extends CommonObject
* This function need a lot of load. If you use it on list, use a cache to execute it one for each product id.
*
* @param int $includedraftpoforvirtual Include draft status and not yet approved Purchase Orders for virtual stock calculation
+ * @param int $dateofvirtualstock Date of virtual stock
* @return int < 0 if KO, > 0 if OK
* @see load_stock(), loadBatchInfo()
*/
- public function load_virtual_stock($includedraftpoforvirtual = null)
+ public function load_virtual_stock($includedraftpoforvirtual = null, $dateofvirtualstock = null)
{
// phpcs:enable
global $conf, $hookmanager, $action;
@@ -5466,7 +5478,7 @@ class Product extends CommonObject
if (isset($includedraftpoforvirtual)) {
$filterStatus = '0,1,2,'.$filterStatus; // 1,2 may have already been inside $filterStatus but it is better to have twice than missing $filterStatus does not include them
}
- $result = $this->load_stats_commande_fournisseur(0, $filterStatus, 1);
+ $result = $this->load_stats_commande_fournisseur(0, $filterStatus, 1, $dateofvirtualstock);
if ($result < 0) {
dol_print_error($this->db, $this->error);
}
@@ -5478,7 +5490,7 @@ class Product extends CommonObject
if (isset($includedraftpoforvirtual)) {
$filterStatus = '0,'.$filterStatus;
}
- $result = $this->load_stats_reception(0, $filterStatus, 1);
+ $result = $this->load_stats_reception(0, $filterStatus, 1, $dateofvirtualstock);
if ($result < 0) {
dol_print_error($this->db, $this->error);
}
@@ -5490,14 +5502,14 @@ class Product extends CommonObject
if (isset($includedraftpoforvirtual)) {
$filterStatus = '0,'.$filterStatus;
}
- $result = $this->load_stats_reception(0, $filterStatus, 1); // Use same tables than when module reception is not used.
+ $result = $this->load_stats_reception(0, $filterStatus, 1, $dateofvirtualstock); // Use same tables than when module reception is not used.
if ($result < 0) {
dol_print_error($this->db, $this->error);
}
$stock_reception_fournisseur = $this->stats_reception['qty'];
}
if (!empty($conf->mrp->enabled)) {
- $result = $this->load_stats_inproduction(0, '1,2', 1);
+ $result = $this->load_stats_inproduction(0, '1,2', 1, $dateofvirtualstock);
if ($result < 0) {
dol_print_error($this->db, $this->error);
}
@@ -6196,8 +6208,6 @@ class Product extends CommonObject
}
}
-
-
/**
* Class to manage products or services.
* Do not use 'Service' as class name since it is already used by APIs.
diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php
index 49242eb47e4..9dfc90b86a4 100644
--- a/htdocs/product/fournisseurs.php
+++ b/htdocs/product/fournisseurs.php
@@ -464,6 +464,9 @@ if ($id > 0 || $ref) {
if (($action == 'add_price' || $action == 'update_price') && $usercancreate) {
$langs->load("suppliers");
+ print "\n";
+ print ' ';
+
if ($rowid) {
$object->fetch_product_fournisseur_price($rowid, 1); //Ignore the math expression when getting the price
print load_fiche_titre($langs->trans("ChangeSupplierPrice"));
@@ -480,7 +483,7 @@ if ($id > 0 || $ref) {
print '';
// Supplier
- print ''.$langs->trans("Supplier").' ';
+ print ' '.$langs->trans("Supplier").' ';
if ($rowid) {
$supplier = new Fournisseur($db);
$supplier->fetch($socid);
@@ -636,7 +639,7 @@ if ($id > 0 || $ref) {
$currencycodetouse = $conf->currency;
}
print $form->selectMultiCurrency($currencycodetouse, "multicurrency_code", 1);
- print ' '.$langs->trans("CurrencyRate").' ';
+ print ' '.$langs->trans("CurrencyRate").' ';
print ' ';
print ' ';
print ' ';
diff --git a/htdocs/product/note.php b/htdocs/product/note.php
index c54bd3637ae..93d40e296e9 100644
--- a/htdocs/product/note.php
+++ b/htdocs/product/note.php
@@ -86,21 +86,21 @@ $form = new Form($db);
$help_url = '';
if (GETPOST("type") == '0' || ($object->type == Product::TYPE_PRODUCT)) {
- $help_url = 'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos';
+ $help_url = 'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos|DE:Modul_Produkte';
}
if (GETPOST("type") == '1' || ($object->type == Product::TYPE_SERVICE)) {
- $help_url = 'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios';
+ $help_url = 'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios|DE:Modul_Leistungen';
}
$title = $langs->trans('ProductServiceCard');
$shortlabel = dol_trunc($object->label, 16);
if (GETPOST("type") == '0' || ($object->type == Product::TYPE_PRODUCT)) {
$title = $langs->trans('Product')." ".$shortlabel." - ".$langs->trans('Notes');
- $help_url = 'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos';
+ $help_url = 'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos|DE:Modul_Produkte';
}
if (GETPOST("type") == '1' || ($object->type == Product::TYPE_SERVICE)) {
$title = $langs->trans('Service')." ".$shortlabel." - ".$langs->trans('Notes');
- $help_url = 'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios';
+ $help_url = 'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios|DE:Modul_Leistungen';
}
llxHeader('', $title, $help_url);
diff --git a/htdocs/product/popuprop.php b/htdocs/product/popuprop.php
index b921f16d02e..17716a4b3ed 100644
--- a/htdocs/product/popuprop.php
+++ b/htdocs/product/popuprop.php
@@ -229,6 +229,7 @@ if ($mode && $mode != '-1') {
}
}
+ $tmpproduct->id = $prodid;
$tmpproduct->ref = $vals['ref'];
$tmpproduct->label = $vals['label'];
$tmpproduct->type = $vals['type'];
diff --git a/htdocs/product/price.php b/htdocs/product/price.php
index 618e5cc6a78..b129a1ff4e5 100644
--- a/htdocs/product/price.php
+++ b/htdocs/product/price.php
@@ -1391,6 +1391,7 @@ if ($action == 'edit_vat' && ($user->rights->produit->creer || $user->rights->se
}
if ($action == 'edit_price' && $object->getRights()->creer) {
+ print ' ';
print load_fiche_titre($langs->trans("NewPrice"), '');
if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
@@ -1915,14 +1916,17 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
// Form to add a new customer price
$maxpricesupplier = $object->min_recommended_price();
- print load_fiche_titre($langs->trans('PriceByCustomer'));
+ print '';
+ print load_fiche_titre($langs->trans('AddCustomerPrice'));
print '