From e87fb1c0dc80aedd63ef6565d31a8d0eee7ffaec Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 7 Jan 2022 12:19:03 +0100 Subject: [PATCH 01/26] add column into table inst --- htdocs/install/mysql/tables/llx_projet_task_time.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/install/mysql/tables/llx_projet_task_time.sql b/htdocs/install/mysql/tables/llx_projet_task_time.sql index 786d8907588..63eadb1177f 100644 --- a/htdocs/install/mysql/tables/llx_projet_task_time.sql +++ b/htdocs/install/mysql/tables/llx_projet_task_time.sql @@ -24,6 +24,7 @@ create table llx_projet_task_time task_datehour datetime, -- day + hour task_date_withhour integer DEFAULT 0, -- 0 by default, 1 if date was entered with start hour task_duration double, + fk_product integer NULL, fk_user integer, thm double(24,8), invoice_id integer DEFAULT NULL, -- If we need to invoice each line of timespent, we can save invoice id here From f5788bef669dfc72407e7237e6bc6927268071b3 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 7 Jan 2022 12:20:27 +0100 Subject: [PATCH 02/26] OK BDD --- .../install/mysql/migration/15.0.0-16.0.0.sql | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 htdocs/install/mysql/migration/15.0.0-16.0.0.sql diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql new file mode 100644 index 00000000000..64df9ca79cb --- /dev/null +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -0,0 +1,34 @@ +-- +-- Be carefull to requests order. +-- This file must be loaded by calling /install/index.php page +-- when current version is 14.0.0 or higher. +-- +-- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y +-- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y +-- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; +-- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); +-- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; +-- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60); +-- To drop a foreign key: ALTER TABLE llx_table DROP FOREIGN KEY fk_name; +-- To create a unique index ALTER TABLE llx_table ADD UNIQUE INDEX uk_table_field (field); +-- To drop an index: -- VMYSQL4.1 DROP INDEX nomindex on llx_table; +-- To drop an index: -- VPGSQL8.2 DROP INDEX nomindex; +-- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_table CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; +-- To make pk to be auto increment (postgres): +-- -- VPGSQL8.2 CREATE SEQUENCE llx_table_rowid_seq OWNED BY llx_table.rowid; +-- -- VPGSQL8.2 ALTER TABLE llx_table ADD PRIMARY KEY (rowid); +-- -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN rowid SET DEFAULT nextval('llx_table_rowid_seq'); +-- -- VPGSQL8.2 SELECT setval('llx_table_rowid_seq', MAX(rowid)) FROM llx_table; +-- To set a field as NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NULL; +-- To set a field as NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name DROP NOT NULL; +-- To set a field as NOT NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NOT NULL; +-- To set a field as NOT NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL; +-- To set a field as default NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL; +-- Note: fields with type BLOB/TEXT can't have default value. +-- To rebuild sequence for postgresql after insert by forcing id autoincrement fields: +-- -- VPGSQL8.2 SELECT dol_util_rebuild_sequences(); + + +-- Missing in v14 or lower +ALTER TABLE llx_projet_task_time ADD COLUMN fk_product integer NULL; From 8ace96f495ff8650c495077d681a02c945bebc04 Mon Sep 17 00:00:00 2001 From: ATM john Date: Fri, 14 Jan 2022 11:46:31 +0100 Subject: [PATCH 03/26] Fix validate class lang load and test for numeric values --- htdocs/core/class/commonobject.class.php | 2 +- htdocs/core/class/validate.class.php | 22 ++++++++++++++++++---- htdocs/langs/en_US/errors.lang | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 029ac6cbfc1..2d5ae6ca78b 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7595,7 +7595,7 @@ abstract class CommonObject } else { return true; } } elseif (in_array($type, array('double', 'real', 'price'))) { // is numeric - if (!$validate->isDuration($fieldValue)) { + if (!$validate->isNumeric($fieldValue)) { $this->setFieldError($fieldKey, $validate->error); return false; } else { return true; } diff --git a/htdocs/core/class/validate.class.php b/htdocs/core/class/validate.class.php index 389bb708e82..4b500b0ae4c 100644 --- a/htdocs/core/class/validate.class.php +++ b/htdocs/core/class/validate.class.php @@ -55,18 +55,17 @@ class Validate { global $langs; - if ($outputLang) { + if (empty($outputLang)) { $this->outputLang = $langs; } else { $this->outputLang = $outputLang; } - if (!is_object($this->outputLang) || !method_exists($outputLang, 'load')) { + if (!is_object($this->outputLang) || !method_exists($this->outputLang, 'load')) { return false; } - /** @var Translate $outputLang */ - $outputLang->load('validate'); + $this->outputLang->loadLangs(array('validate', 'errors')); $this->db = $db; } @@ -229,6 +228,21 @@ class Validate return true; } + /** + * Check Duration validity + * + * @param mixed $string to validate + * @return boolean Validity is ok or not + */ + public function isNumeric($string) + { + if (!is_numeric($string)) { + $this->error = $this->outputLang->trans('RequireValidNumeric'); + return false; + } + return true; + } + /** * Check for boolean validity * diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 7f4ca7b074f..293bf4ad53b 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -315,6 +315,7 @@ RequireAtLeastXString = Requires at least %s character(s) RequireXStringMax = Requires %s character(s) max RequireAtLeastXDigits = Requires at least %s digit(s) RequireXDigitsMax = Requires %s digit(s) max +RequireValidNumeric = Requires a numeric value RequireValidEmail = Email address is not valid RequireMaxLength = Length must be less than %s chars RequireMinLength = Length must be more than %s char(s) From a394713f1bb8eda51d7a35c179bf3ee22683df79 Mon Sep 17 00:00:00 2001 From: ATM john Date: Fri, 14 Jan 2022 11:51:07 +0100 Subject: [PATCH 04/26] Fix doc comment --- htdocs/core/class/validate.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/validate.class.php b/htdocs/core/class/validate.class.php index 4b500b0ae4c..61251167c21 100644 --- a/htdocs/core/class/validate.class.php +++ b/htdocs/core/class/validate.class.php @@ -229,7 +229,7 @@ class Validate } /** - * Check Duration validity + * Check numeric validity * * @param mixed $string to validate * @return boolean Validity is ok or not From a9c76f2e44097b1b087b66f46f61788d9f029786 Mon Sep 17 00:00:00 2001 From: lvessiller Date: Fri, 14 Jan 2022 16:09:30 +0100 Subject: [PATCH 05/26] FIX replace print error with event message when error on update line in supplier order --- htdocs/fourn/commande/card.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index c85d1f56c29..fa77765156c 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -792,8 +792,7 @@ if (empty($reshook)) { $db->rollback(); - dol_print_error($db, $object->error); - exit; + setEventMessages($object->error, $object->errors, 'errors'); } } From 89869a248583bf8cb58f9f4004e727cfe75e51ef Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Sat, 15 Jan 2022 12:09:36 +0100 Subject: [PATCH 06/26] Fix view after generate export --- htdocs/admin/tools/dolibarr_export.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index d6700cedf04..5f9dc97ba44 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -400,8 +400,6 @@ print ''; print ''; print ''; -print ''; -print ''; @@ -538,6 +536,8 @@ if (!empty($_SESSION["commandbackuptorun"])) { print " \n"; +print ''; +print ''; print " \n"; From ea55712d1b7b9c9d9710c6a7151ca0bed7f8651a Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 15 Jan 2022 23:04:56 +0100 Subject: [PATCH 07/26] Fix missing require class project --- htdocs/ticket/messaging.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/ticket/messaging.php b/htdocs/ticket/messaging.php index 49f15412965..9ee2b627118 100644 --- a/htdocs/ticket/messaging.php +++ b/htdocs/ticket/messaging.php @@ -204,6 +204,7 @@ if (!empty($conf->projet->enabled)) } } else { if (!empty($object->fk_project)) { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $proj = new Project($db); $proj->fetch($object->fk_project); $morehtmlref .= $proj->getNomUrl(1); From 22a3b5ea78a5fa211803bcca04a1d55fee3ba909 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 18 Jan 2022 16:24:28 +0100 Subject: [PATCH 08/26] FIX deletion of supplier order when draft --- htdocs/fourn/commande/card.php | 15 ++++++++------- htdocs/modulebuilder/template/myobject_card.php | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 915354b50b6..a44a1be11be 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -85,13 +85,6 @@ $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (!empty($con $datelivraison = dol_mktime(GETPOST('liv_hour', 'int'), GETPOST('liv_min', 'int'), GETPOST('liv_sec', 'int'), GETPOST('liv_month', 'int'), GETPOST('liv_day', 'int'), GETPOST('liv_year', 'int')); - -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande'); - // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('ordersuppliercard', 'globalcard')); @@ -101,6 +94,10 @@ $extrafields = new ExtraFields($db); // fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); +if ($user->socid) { + $socid = $user->socid; +} + // Load object if ($id > 0 || !empty($ref)) { $ret = $object->fetch($id, $ref); @@ -124,6 +121,10 @@ if ($id > 0 || !empty($ref)) { } } +// Security check +$isdraft = (isset($object->statut) && ($object->statut == $object::STATUS_DRAFT) ? 1 : 0); +$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande', 'fk_soc', 'rowid', $isdraft); + // Common permissions $usercanread = ($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->lire); $usercancreate = ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer); diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index b074412b6b3..346e9d907e6 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -132,7 +132,7 @@ $upload_dir = $conf->mymodule->multidir_output[isset($object->entity) ? $object- // Security check (enable the most restrictive one) //if ($user->socid > 0) accessforbidden(); //if ($user->socid > 0) $socid = $user->socid; -//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +//$isdraft = (isset($object->status) && ($object->status == $object::STATUS_DRAFT) ? 1 : 0); //restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); //if (empty($conf->mymodule->enabled)) accessforbidden(); //if (!$permissiontoread) accessforbidden(); From aa2b244bf399d6a56f1bff4c03772224e888b39e Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 19 Jan 2022 13:31:51 +0100 Subject: [PATCH 09/26] fix wordpress indent --- .../OAuth/OAuth2/Service/WordPress.php | 153 ++++++++++-------- 1 file changed, 83 insertions(+), 70 deletions(-) diff --git a/htdocs/includes/OAuth/OAuth2/Service/WordPress.php b/htdocs/includes/OAuth/OAuth2/Service/WordPress.php index c59e90c605f..79a13d00e2d 100755 --- a/htdocs/includes/OAuth/OAuth2/Service/WordPress.php +++ b/htdocs/includes/OAuth/OAuth2/Service/WordPress.php @@ -11,87 +11,100 @@ use OAuth\Common\Http\Exception\TokenResponseException; use OAuth\OAuth2\Service\Exception\InvalidAccessTypeException; use OAuth\Common\Http\Uri\Uri; +/** + * Class For WordPress OAuth + */ class WordPress extends AbstractService { - protected $accessType = 'online'; + /** + * @var string + */ + protected $accessType = 'online'; - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true); + /** + * Construct + * + * @param CredentialsInterface $credentials credentials + * @param ClientInterface $httpClient httpClient + * @param TokenStorageInterface $storage storage + * @param $scopes scope + * @param UriInterface|null $baseApiUri baseApiUri + * @throws Exception\InvalidScopeException + */ + public function __construct(CredentialsInterface $credentials, ClientInterface $httpClient, TokenStorageInterface $storage, $scopes = array(), UriInterface $baseApiUri = null) + { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true); - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://addresse_de_votre_site_wordpress'); - } - } -/* - // LDR CHANGE Add approval_prompt to force the prompt if value is set to 'force' so it force return of a "refresh token" in addition to "standard token" - public $approvalPrompt='auto'; - public function setApprouvalPrompt($prompt) - { - if (!in_array($prompt, array('auto', 'force'), true)) { - // @todo Maybe could we rename this exception - throw new InvalidAccessTypeException('Invalid approuvalPrompt, expected either auto or force.'); - } - $this->approvalPrompt = $prompt; - }*/ - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri(sprintf('%s/oauth/authorize', $this->baseApiUri)); - } + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://addresse_de_votre_site_wordpress'); + } + } + /* + // LDR CHANGE Add approval_prompt to force the prompt if value is set to 'force' so it force return of a "refresh token" in addition to "standard token" + public $approvalPrompt='auto'; + public function setApprouvalPrompt($prompt) + { + if (!in_array($prompt, array('auto', 'force'), true)) { + // @todo Maybe could we rename this exception + throw new InvalidAccessTypeException('Invalid approuvalPrompt, expected either auto or force.'); + } + $this->approvalPrompt = $prompt; + }*/ - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri(sprintf('%s/oauth/token', $this->baseApiUri)); - } + /** + * @return Uri + */ + public function getAuthorizationEndpoint() + { + return new Uri(sprintf('%s/oauth/authorize', $this->baseApiUri)); + } - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - global $conf; - return empty($conf->global->OAUTH_WORDPRESS_AUTHORIZATION_METHOD_QUERY_STRING) ? static::AUTHORIZATION_METHOD_HEADER_BEARER : static::AUTHORIZATION_METHOD_QUERY_STRING; - } + /** + * @return Uri + */ + public function getAccessTokenEndpoint() + { + return new Uri(sprintf('%s/oauth/token', $this->baseApiUri)); + } - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); + /** + * @return int + */ + protected function getAuthorizationMethod() + { + global $conf; + return empty($conf->global->OAUTH_WORDPRESS_AUTHORIZATION_METHOD_QUERY_STRING) ? static::AUTHORIZATION_METHOD_HEADER_BEARER : static::AUTHORIZATION_METHOD_QUERY_STRING; + } - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response: "'.(isset($responseBody)?$responseBody:'NULL').'"'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '" : "'.$data['error_description'].'"'); - } + /** + * @param $responseBody responseBody + * @return StdOAuth2Token + * @throws TokenResponseException + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifetime($data['expires_in']); + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response: "'.(isset($responseBody)?$responseBody:'NULL').'"'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '" : "'.$data['error_description'].'"'); + } - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifetime($data['expires_in']); - unset($data['access_token']); - unset($data['expires_in']); + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } - $token->setExtraParams($data); + unset($data['access_token']); + unset($data['expires_in']); - return $token; - } + $token->setExtraParams($data); + + return $token; + } } From c8589970af00a70e7dcb51068a977cccc0e5f40c Mon Sep 17 00:00:00 2001 From: atm-lena Date: Wed, 19 Jan 2022 15:33:30 +0100 Subject: [PATCH 10/26] FIX : event created from contract not linked to object origin --- htdocs/contrat/agenda.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/contrat/agenda.php b/htdocs/contrat/agenda.php index 94232aa6afd..c320b708ccb 100644 --- a/htdocs/contrat/agenda.php +++ b/htdocs/contrat/agenda.php @@ -244,6 +244,8 @@ if ($id > 0) { $newcardbutton = ''; if (!empty($conf->agenda->enabled)) { if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) { + $backtopage = $_SERVER['PHP_SELF'].'?id='.$object->id; + $out = '&origin='.urlencode($object->element).'&originid='.$object->id.'&backtopage='.urlencode($backtopage); $newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out); } } From db9a26f8d426bbd292e4df84eefaab40e21cf1e3 Mon Sep 17 00:00:00 2001 From: atm-lena Date: Wed, 19 Jan 2022 15:35:09 +0100 Subject: [PATCH 11/26] FIX error urlencode --- htdocs/contrat/agenda.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/contrat/agenda.php b/htdocs/contrat/agenda.php index c320b708ccb..a291a9d8761 100644 --- a/htdocs/contrat/agenda.php +++ b/htdocs/contrat/agenda.php @@ -245,7 +245,7 @@ if ($id > 0) { if (!empty($conf->agenda->enabled)) { if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) { $backtopage = $_SERVER['PHP_SELF'].'?id='.$object->id; - $out = '&origin='.urlencode($object->element).'&originid='.$object->id.'&backtopage='.urlencode($backtopage); + $out = '&origin='.$object->element.'&originid='.$object->id.'&backtopage='.urlencode($backtopage); $newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out); } } From 115f022ae9bb332ef91bc4be6ca2c8db5c52312d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cserveny=2C=20Tam=C3=A1s?= Date: Thu, 20 Jan 2022 00:55:52 +0100 Subject: [PATCH 12/26] Check if the lines in create is type object (like supplier invoice) --- .../class/fournisseur.commande.class.php | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index fc89ee06caa..6def2a9faf4 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1357,32 +1357,38 @@ class CommandeFournisseur extends CommonOrder if ($this->id) { $num = count($this->lines); - + // insert products details into database for ($i = 0; $i < $num; $i++) { - $this->special_code = $this->lines[$i]->special_code; // TODO : remove this in 9.0 and add special_code param to addline() + $line = $this->lines[$i]; + if (!is_object($line)) { + $line = (object) $line; + } + + $this->special_code = $line->special_code; // TODO : remove this in 9.0 and add special_code param to addline() + // This include test on qty if option SUPPLIER_ORDER_WITH_NOPRICEDEFINED is not set $result = $this->addline( - $this->lines[$i]->desc, - $this->lines[$i]->subprice, - $this->lines[$i]->qty, - $this->lines[$i]->tva_tx, - $this->lines[$i]->localtax1_tx, - $this->lines[$i]->localtax2_tx, - $this->lines[$i]->fk_product, + $line->desc, + $line->subprice, + $line->qty, + $line->tva_tx, + $line->localtax1_tx, + $line->localtax2_tx, + $line->fk_product, 0, - $this->lines[$i]->ref_fourn, // $this->lines[$i]->ref_fourn comes from field ref into table of lines. Value may ba a ref that does not exists anymore, so we first try with value of product - $this->lines[$i]->remise_percent, + $line->ref_fourn, // $line->ref_fourn comes from field ref into table of lines. Value may ba a ref that does not exists anymore, so we first try with value of product + $line->remise_percent, 'HT', 0, - $this->lines[$i]->product_type, - $this->lines[$i]->info_bits, + $line->product_type, + $line->info_bits, false, - $this->lines[$i]->date_start, - $this->lines[$i]->date_end, - $this->lines[$i]->array_options, - $this->lines[$i]->fk_unit + $line->date_start, + $line->date_end, + $line->array_options, + $line->fk_unit ); if ($result < 0) { dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING); // do not use dol_print_error here as it may be a functionnal error From 400d28238c58de1929232560e198e452616c694f Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 20 Jan 2022 00:09:52 +0000 Subject: [PATCH 13/26] Fixing style errors. --- htdocs/fourn/class/fournisseur.commande.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 6def2a9faf4..b86834ee206 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1357,17 +1357,17 @@ class CommandeFournisseur extends CommonOrder if ($this->id) { $num = count($this->lines); - + // insert products details into database for ($i = 0; $i < $num; $i++) { - $line = $this->lines[$i]; - if (!is_object($line)) { + $line = $this->lines[$i]; + if (!is_object($line)) { $line = (object) $line; } - + $this->special_code = $line->special_code; // TODO : remove this in 9.0 and add special_code param to addline() - + // This include test on qty if option SUPPLIER_ORDER_WITH_NOPRICEDEFINED is not set $result = $this->addline( $line->desc, From 03af9ea3f3aafc6337444f597dd25067039641cb Mon Sep 17 00:00:00 2001 From: lmarcouiller Date: Thu, 20 Jan 2022 14:54:54 +0100 Subject: [PATCH 14/26] remove false positive on carriage return --- htdocs/product/inventory/inventory.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 82747fb8360..95c9e2972cb 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -630,7 +630,10 @@ if ($object->id > 0) { errortab3 = []; errortab4 = []; - if(textarray[0] != ""){ + textarray = textarray.filter(function(value){ + return value != ""; + }); + if(textarray.some((element) => element != "")){ $(".expectedqty").each(function(){ id = this.id; console.log("Analyze line "+id+" in inventory"); @@ -851,7 +854,7 @@ if ($object->id > 0) { print ''; print ''.$langs->trans("Warehouse").''; print ''.$langs->trans("Product").''; - if ($conf->productbatch->enabled) { + if (!empty($conf->productbatch->enabled)) { print ''; print $langs->trans("Batch"); print ''; @@ -881,7 +884,7 @@ if ($object->id > 0) { print ''; print $form->select_produits((GETPOSTISSET('fk_product') ? GETPOST('fk_product', 'int') : $object->fk_product), 'fk_product', '', 0, 0, -1, 2, '', 0, null, 0, '1', 0, 'maxwidth300'); print ''; - if ($conf->productbatch->enabled) { + if (!empty($conf->productbatch->enabled)) { print ''; print ''; print ''; @@ -927,6 +930,7 @@ if ($object->id > 0) { } // Load real stock we have now + $option = ''; if (isset($cacheOfProducts[$obj->fk_product])) { $product_static = $cacheOfProducts[$obj->fk_product]; } else { @@ -948,7 +952,7 @@ if ($object->id > 0) { print $product_static->getNomUrl(1).' - '.$product_static->label; print ''; - if ($conf->productbatch->enabled) { + if (!empty($conf->productbatch->enabled)) { print ''; print $obj->batch; print ''; @@ -959,7 +963,7 @@ if ($object->id > 0) { $valuetoshow = $obj->qty_stock; // For inventory not yet close, we overwrite with the real value in stock now if ($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) { - if ($conf->productbatch->enabled && $product_static->hasbatch()) { + if (!empty($conf->productbatch->enabled) && $product_static->hasbatch()) { $valuetoshow = $product_static->stock_warehouse[$obj->fk_warehouse]->detail_batch[$obj->batch]->qty; } else { $valuetoshow = $product_static->stock_warehouse[$obj->fk_warehouse]->real; From 259c94e3201d4683aa738042d8e781cf94648806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cserveny=2C=20Tam=C3=A1s?= Date: Thu, 20 Jan 2022 17:57:21 +0100 Subject: [PATCH 15/26] fix docker build setup --- build/docker/Dockerfile | 13 ++++--------- build/docker/docker-compose.yml | 3 +++ htdocs/install/default.css | 2 -- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile index dca74e9e720..e38ad20931d 100644 --- a/build/docker/Dockerfile +++ b/build/docker/Dockerfile @@ -39,15 +39,10 @@ RUN chmod +x /usr/local/bin/docker-run.sh RUN pecl install xdebug && docker-php-ext-enable xdebug RUN echo 'zend_extension="/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so"' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.remote_autostart=1' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.remote_enable=1' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.default_enable=1' >> ${PHP_INI_DIR}/php.ini -#RUN echo 'xdebug.remote_host=docker.host' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.remote_port=9000' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.remote_connect_back=1' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.profiler_enable=0' >> ${PHP_INI_DIR}/php.ini -RUN echo 'xdebug.remote_log="/tmp/xdebug.log"' >> ${PHP_INI_DIR}/php.ini -#RUN echo 'localhost docker.host' >> /etc/hosts +RUN echo 'xdebug.mode=debug' >> ${PHP_INI_DIR}/php.ini +RUN echo 'xdebug.client_host=host.docker.internal' >> ${PHP_INI_DIR}/php.ini +RUN echo 'xdebug.client_port=9003' >> ${PHP_INI_DIR}/php.ini +RUN echo 'xdebug.idekey="netbeans-xdebug"' >> ${PHP_INI_DIR}/php.ini # set up sendmail config, to use maildev RUN echo "account default" > /etc/msmtprc diff --git a/build/docker/docker-compose.yml b/build/docker/docker-compose.yml index 2167f069f25..8994043cd8a 100644 --- a/build/docker/docker-compose.yml +++ b/build/docker/docker-compose.yml @@ -46,6 +46,9 @@ services: networks: - internal-pod - external-pod + extra_hosts: + - "localhost.localdomain:127.0.0.1" + - "host.docker.internal:host-gateway" mail: image: maildev/maildev diff --git a/htdocs/install/default.css b/htdocs/install/default.css index 726f1d2d0c2..96c671d1472 100644 --- a/htdocs/install/default.css +++ b/htdocs/install/default.css @@ -473,5 +473,3 @@ table.tablesupport { width: 100%; } } - -} From 284fcf3ad57dd562995e0a2554a5bb27acacf308 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 22 Jan 2022 13:19:29 +0100 Subject: [PATCH 16/26] FIX Company logo not found in some cases on some templates --- .../supplier_order/doc/pdf_cornas.modules.php | 34 ++++++++++++------- .../doc/pdf_muscadet.modules.php | 34 ++++++++++++------- .../doc/pdf_aurore.modules.php | 34 ++++++++++++------- 3 files changed, 66 insertions(+), 36 deletions(-) diff --git a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php index 0018bc7ff7f..e823ceebb25 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php @@ -1245,20 +1245,30 @@ class pdf_cornas extends ModelePDFSuppliersOrders $pdf->SetXY($this->marge_gauche, $posy); // Logo - $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; - if ($this->emetteur->logo) { - if (is_readable($logo)) { - $height = pdf_getHeightForLogo($logo); - $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) { + if ($this->emetteur->logo) { + $logodir = $conf->mycompany->dir_output; + if (!empty($conf->mycompany->multidir_output[$object->entity])) { + $logodir = $conf->mycompany->multidir_output[$object->entity]; + } + if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) { + $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small; + } else { + $logo = $logodir.'/logos/'.$this->emetteur->logo; + } + if (is_readable($logo)) { + $height = pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } else { + $pdf->SetTextColor(200, 0, 0); + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } } else { - $pdf->SetTextColor(200, 0, 0); - $pdf->SetFont('', 'B', $default_font_size - 2); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToModuleSetup"), 0, 'L'); + $text = $this->emetteur->name; + $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection); } - } else { - $text = $this->emetteur->name; - $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection); } $pdf->SetFont('', 'B', $default_font_size + 3); diff --git a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php index 8c706f59db3..736e23519bc 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php @@ -1153,20 +1153,30 @@ class pdf_muscadet extends ModelePDFSuppliersOrders $pdf->SetXY($this->marge_gauche, $posy); // Logo - $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; - if ($this->emetteur->logo) { - if (is_readable($logo)) { - $height = pdf_getHeightForLogo($logo); - $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) { + if ($this->emetteur->logo) { + $logodir = $conf->mycompany->dir_output; + if (!empty($conf->mycompany->multidir_output[$object->entity])) { + $logodir = $conf->mycompany->multidir_output[$object->entity]; + } + if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) { + $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small; + } else { + $logo = $logodir.'/logos/'.$this->emetteur->logo; + } + if (is_readable($logo)) { + $height = pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } else { + $pdf->SetTextColor(200, 0, 0); + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } } else { - $pdf->SetTextColor(200, 0, 0); - $pdf->SetFont('', 'B', $default_font_size - 2); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToModuleSetup"), 0, 'L'); + $text = $this->emetteur->name; + $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection); } - } else { - $text = $this->emetteur->name; - $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection); } $pdf->SetFont('', 'B', $default_font_size + 3); diff --git a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php index 1bf47275599..7e1b1105452 100644 --- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php @@ -1290,20 +1290,30 @@ class pdf_aurore extends ModelePDFSupplierProposal $pdf->SetXY($this->marge_gauche, $posy); // Logo - $logo = $conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; - if ($this->emetteur->logo) { - if (is_readable($logo)) { - $height = pdf_getHeightForLogo($logo); - $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) { + if ($this->emetteur->logo) { + $logodir = $conf->mycompany->dir_output; + if (!empty($conf->mycompany->multidir_output[$object->entity])) { + $logodir = $conf->mycompany->multidir_output[$object->entity]; + } + if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) { + $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small; + } else { + $logo = $logodir.'/logos/'.$this->emetteur->logo; + } + if (is_readable($logo)) { + $height = pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } else { + $pdf->SetTextColor(200, 0, 0); + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } } else { - $pdf->SetTextColor(200, 0, 0); - $pdf->SetFont('', 'B', $default_font_size - 2); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + $text = $this->emetteur->name; + $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection); } - } else { - $text = $this->emetteur->name; - $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); } $pdf->SetFont('', 'B', $default_font_size + 3); From fefbaa739a3b01a978200b99672f69468350b9f7 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Wed, 19 Jan 2022 21:18:49 +0100 Subject: [PATCH 17/26] fix : bad path --- htdocs/societe/class/societe.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 7490fca0265..a49bf478763 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -4870,7 +4870,7 @@ class Societe extends CommonObject { global $langs; - require_once DOL_DOCUMENT_ROOT.'/parntership/class/partnership.class.php'; + require_once DOL_DOCUMENT_ROOT.'/partnership/class/partnership.class.php'; $this->partnerships[] = array(); From 4888d127e02dc2ed5a40af863d4ed0a34f3efa69 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Jan 2022 12:59:15 +0100 Subject: [PATCH 18/26] Make virus file no more detected. --- test/phpunit/testvirus.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/phpunit/testvirus.txt b/test/phpunit/testvirus.txt index a2463df6d64..86bb55dac62 100644 --- a/test/phpunit/testvirus.txt +++ b/test/phpunit/testvirus.txt @@ -1 +1,2 @@ -X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H* \ No newline at end of file +# Remove this line and replace the "AB" with "X5" at begin of line to get a file that is detected by antiviruses. +ABO!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H* From e392d98beb9e44351d70d213f99a6967a7e9e675 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Jan 2022 13:43:48 +0100 Subject: [PATCH 19/26] Fix hook --- htdocs/emailcollector/class/emailcollector.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index ff29e56b1e7..e2493a338fd 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -2365,8 +2365,9 @@ class EmailCollector extends CommonObject // this code action is hook..... for support this call global $hookmanager; - if (is_object($hookmanager)) { - $hookmanager->initHooks(array('emailcollectorcard')); + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); } $parameters = array( From adf74925752f99f33d3f921aed4edfaf230b2110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cserveny=2C=20Tam=C3=A1s?= Date: Sun, 23 Jan 2022 16:26:14 +0100 Subject: [PATCH 20/26] migrate missing properties --- build/docker/Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile index e38ad20931d..e39f96b0b27 100644 --- a/build/docker/Dockerfile +++ b/build/docker/Dockerfile @@ -40,8 +40,11 @@ RUN chmod +x /usr/local/bin/docker-run.sh RUN pecl install xdebug && docker-php-ext-enable xdebug RUN echo 'zend_extension="/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so"' >> ${PHP_INI_DIR}/php.ini RUN echo 'xdebug.mode=debug' >> ${PHP_INI_DIR}/php.ini +RUN echo 'xdebug.start_with_request=yes' >> ${PHP_INI_DIR}/php.ini RUN echo 'xdebug.client_host=host.docker.internal' >> ${PHP_INI_DIR}/php.ini RUN echo 'xdebug.client_port=9003' >> ${PHP_INI_DIR}/php.ini +RUN echo 'xdebug.discover_client_host=true' >> ${PHP_INI_DIR}/php.ini +#RUN echo 'xdebug.log="/tmp/xdebug.log"' >> ${PHP_INI_DIR}/php.ini RUN echo 'xdebug.idekey="netbeans-xdebug"' >> ${PHP_INI_DIR}/php.ini # set up sendmail config, to use maildev From 053b402202900cf6a9e5e35d2456b77923c094a2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 23 Jan 2022 19:20:13 +0100 Subject: [PATCH 21/26] Fix for notes standardization #19835 --- .../adherents/class/adherent_type.class.php | 31 ++++++++++++++----- htdocs/adherents/class/subscription.class.php | 11 +++++-- htdocs/user/class/user.class.php | 2 +- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 90f160e7932..18a91efaacd 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -94,9 +94,15 @@ class AdherentType extends CommonObject */ public $amount; - /** @var string Public note */ + /** + * @var string Public note + * @deprecated + */ public $note; + /** @var string Public note */ + public $note_public; + /** @var integer Can vote */ public $vote; @@ -358,6 +364,10 @@ class AdherentType extends CommonObject $this->label = trim($this->label); + if (empty($this->note_public) && !empty($this->note)) { // For backward compatibility + $this->note_public = $this->note; + } + $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."adherent_type "; @@ -368,14 +378,14 @@ class AdherentType extends CommonObject $sql .= "subscription = '".$this->db->escape($this->subscription)."',"; $sql .= "amount = ".((empty($this->amount) && $this->amount == '') ? 'null' : ((float) $this->amount)).","; $sql .= "duration = '".$this->db->escape($this->duration_value.$this->duration_unit)."',"; - $sql .= "note = '".$this->db->escape($this->note)."',"; + $sql .= "note = '".$this->db->escape($this->note_public)."',"; $sql .= "vote = ".(integer) $this->db->escape($this->vote).","; $sql .= "mail_valid = '".$this->db->escape($this->mail_valid)."'"; $sql .= " WHERE rowid =".((int) $this->id); $result = $this->db->query($sql); if ($result) { - $this->description = $this->db->escape($this->note); + $this->description = $this->db->escape($this->note_public); // Multilangs if (!empty($conf->global->MAIN_MULTILANGS)) { @@ -461,7 +471,7 @@ class AdherentType extends CommonObject { global $langs, $conf; - $sql = "SELECT d.rowid, d.libelle as label, d.morphy, d.statut as status, d.duration, d.subscription, d.amount, d.mail_valid, d.note, d.vote"; + $sql = "SELECT d.rowid, d.libelle as label, d.morphy, d.statut as status, d.duration, d.subscription, d.amount, d.mail_valid, d.note as note_public, d.vote"; $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; $sql .= " WHERE d.rowid = ".(int) $rowid; @@ -483,7 +493,8 @@ class AdherentType extends CommonObject $this->subscription = $obj->subscription; $this->amount = $obj->amount; $this->mail_valid = $obj->mail_valid; - $this->note = $obj->note; + $this->note = $obj->note_public; // deprecated + $this->note_public = $obj->note_public; $this->vote = $obj->vote; // multilangs @@ -792,12 +803,16 @@ class AdherentType extends CommonObject // Object classes $info["objectclass"] = explode(',', $conf->global->LDAP_MEMBER_TYPE_OBJECT_CLASS); + if (empty($this->note_public) && !empty($this->note)) { // For backward compatibility + $this->note_public = $this->note; + } + // Champs if ($this->label && !empty($conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME)) { $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME] = $this->label; } - if ($this->note && !empty($conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION)) { - $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION] = dol_string_nohtmltag($this->note, 0, 'UTF-8', 1); + if ($this->note_public && !empty($conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION)) { + $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION] = dol_string_nohtmltag($this->note_public, 0, 'UTF-8', 1); } if (!empty($conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)) { $valueofldapfield = array(); @@ -829,7 +844,7 @@ class AdherentType extends CommonObject $this->specimen = 1; $this->label = 'MEMBERS TYPE SPECIMEN'; - $this->note = 'This is a note'; + $this->note_public = 'This is a public note'; $this->mail_valid = 'This is welcome email'; $this->subscription = 1; $this->vote = 0; diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php index cae5dd07beb..885c8981d93 100644 --- a/htdocs/adherents/class/subscription.class.php +++ b/htdocs/adherents/class/subscription.class.php @@ -215,7 +215,7 @@ class Subscription extends CommonObject $sql .= " tms,"; $sql .= " dateadh as dateh,"; $sql .= " datef,"; - $sql .= " subscription, note, fk_bank"; + $sql .= " subscription, note as note_public, fk_bank"; $sql .= " FROM ".MAIN_DB_PREFIX."subscription"; $sql .= " WHERE rowid=".((int) $rowid); @@ -235,7 +235,8 @@ class Subscription extends CommonObject $this->dateh = $this->db->jdate($obj->dateh); $this->datef = $this->db->jdate($obj->datef); $this->amount = $obj->subscription; - $this->note = $obj->note; + $this->note = $obj->note_public; // deprecated + $this->note_public = $obj->note_public; $this->fk_bank = $obj->fk_bank; return 1; } else { @@ -266,10 +267,14 @@ class Subscription extends CommonObject return -1; } + if (empty($this->note_public) && !empty($this->note)) { // For backward compatibility + $this->note_public = $this->note; + } + $sql = "UPDATE ".MAIN_DB_PREFIX."subscription SET "; $sql .= " fk_type = ".((int) $this->fk_type).","; $sql .= " fk_adherent = ".((int) $this->fk_adherent).","; - $sql .= " note=".($this->note ? "'".$this->db->escape($this->note)."'" : 'null').","; + $sql .= " note=".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : 'null').","; $sql .= " subscription = ".price2num($this->amount).","; $sql .= " dateadh='".$this->db->idate($this->dateh)."',"; $sql .= " datef='".$this->db->idate($this->datef)."',"; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index a6b6b5af1e6..d1cf9a40b95 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -524,7 +524,7 @@ class User extends CommonObject $this->admin = $obj->admin; $this->note_public = $obj->note_public; $this->note_private = $obj->note_private; - $this->note = $obj->note_private; + $this->note = $obj->note_private; // deprecated $this->statut = $obj->statut; $this->photo = $obj->photo; $this->openid = $obj->openid; From 00eabded6d037541bb50b90fdf5e253436b5e1d6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 24 Jan 2022 12:43:42 +0100 Subject: [PATCH 22/26] Fix phpunit --- htdocs/core/lib/functions.lib.php | 1 + htdocs/user/class/user.class.php | 4 ++-- test/phpunit/UserTest.php | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 76ac0df05b1..3d98530ffd7 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1544,6 +1544,7 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename = // This is when PHP session is ran outside a web server, like from Linux command line (Not always defined, but usefull if OS defined it). $data['ip'] = '???@'.$_SERVER['LOGNAME']; } + // Loop on each log handler and send output foreach ($conf->loghandlers as $loghandlerinstance) { if ($restricttologhandler && $loghandlerinstance->code != $restricttologhandler) { diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index d1cf9a40b95..6345cac8b1a 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1905,7 +1905,7 @@ class User extends CommonObject // Update password if (!empty($this->pass)) { if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) { - // Si mot de passe saisi et different de celui en base + // If a new value for password is set and different than the one crypted into database $result = $this->setPassword($user, $this->pass, 0, $notrigger, $nosyncmemberpass); if ($result < 0) { return -5; @@ -3080,7 +3080,7 @@ class User extends CommonObject $this->personal_mobile = '0999999996'; $this->admin = 0; $this->login = 'dolibspec'; - $this->pass = 'dolibspec'; + $this->pass = 'dolibSpec+@123'; //$this->pass_indatabase='dolibspec'; Set after a fetch //$this->pass_indatabase_crypted='e80ca5a88c892b0aaaf7e154853bccab'; Set after a fetch $this->datec = $now; diff --git a/test/phpunit/UserTest.php b/test/phpunit/UserTest.php index b8025a3cd41..699e9fd89f0 100644 --- a/test/phpunit/UserTest.php +++ b/test/phpunit/UserTest.php @@ -143,11 +143,13 @@ class UserTest extends PHPUnit\Framework\TestCase $langs=$this->savlangs; $db=$this->savdb; + print __METHOD__." USER_PASSWORD_GENERATED=".getDolGlobalString('USER_PASSWORD_GENERATED')."\n"; + $localobject=new User($this->savdb); $localobject->initAsSpecimen(); $result=$localobject->create($user); - $this->assertLessThan($result, 0); + $this->assertLessThan($result, 0, 'Creation of user has failed: '.$localobject->error); print __METHOD__." result=".$result."\n"; return $result; } From 1eb4d7625333d653a735b3cf6c1efb6571635491 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 24 Jan 2022 13:15:32 +0100 Subject: [PATCH 23/26] Clean code --- htdocs/admin/commande.php | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php index 1e977fb48df..24a45bb413a 100644 --- a/htdocs/admin/commande.php +++ b/htdocs/admin/commande.php @@ -158,18 +158,6 @@ if ($action == 'updateMask') { $error++; } - if (!$error) { - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } else { - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} elseif ($action == "setshippableiconinlist") { - // Activate Set Shippable Icon In List - $setshippableiconinlist = GETPOST('value', 'int'); - $res = dolibarr_set_const($db, "SHIPPABLE_ORDER_ICON_IN_LIST", $setshippableiconinlist, 'yesno', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } if (!$error) { setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); } else { @@ -646,25 +634,6 @@ print '\n"; print ''; -// Shippable Icon in List -/* Kept as hidden feature for the moment, result seems bugged. -Where is definition of "shippable" according to all different STOCK_CALCULATE_... options ? - -print ''; -print ''.$langs->trans("ShippableOrderIconInList").''; -print ' '; -print ''; -if (!empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) { - print ''; - print img_picto($langs->trans("Activated"),'switch_on'); -} else { - print ''; - print img_picto($langs->trans("Disabled"),'switch_off'); -} -print ''; -print ''; -*/ - /* // Seems to be not so used. So kept hidden for the moment to avoid dangerous options inflation. // Ask for payment bank during order From 6b5c0769b843c8de8f0d57f1460d438e2398bde4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 24 Jan 2022 14:09:53 +0100 Subject: [PATCH 24/26] FIX #19786 --- htdocs/commande/class/commande.class.php | 12 +++++++--- htdocs/commande/list.php | 30 +++++++++++++----------- htdocs/expedition/card.php | 7 ++++-- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index f60a91ae3df..48b7e499dbb 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -261,6 +261,11 @@ class Commande extends CommonOrder //! key of pos source ('0', '1', ...) public $pos_source; + /** + * @var array Array with line of all shipments + */ + public $expeditions; + /** * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') @@ -2004,9 +2009,9 @@ class Commande extends CommonOrder /** * Load array lines * - * @param int $only_product Return only physical products, not services + * @param int $only_product Return only physical products, not services * @param int $loadalsotranslation Return translation for products - * @return int <0 if KO, >0 if OK + * @return int <0 if KO, >0 if OK */ public function fetch_lines($only_product = 0, $loadalsotranslation = 0) { @@ -2201,9 +2206,10 @@ class Commande extends CommonOrder * Note: For a dedicated shipment, the fetch_lines can be used to load the qty_asked and qty_shipped. This function is use to return qty_shipped cumulated for the order * * @param int $filtre_statut Filter on shipment status + * @param int $fk_product Add a filter on a product * @return int <0 if KO, Nb of lines found if OK */ - public function loadExpeditions($filtre_statut = -1) + public function loadExpeditions($filtre_statut = -1, $fk_product = 0) { $this->expeditions = array(); diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 8fc93a233c2..717b57ae8b1 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1854,10 +1854,13 @@ if ($resql) { print ''; if (!empty($show_shippable_command) && !empty($conf->stock->enabled)) { if (($obj->fk_statut > $generic_commande::STATUS_DRAFT) && ($obj->fk_statut < $generic_commande::STATUS_CLOSED)) { - $generic_commande->getLinesArray(); // This set ->lines + $generic_commande->getLinesArray(); // Load array ->lines + $generic_commande->loadExpeditions(); // Load array ->expeditions $numlines = count($generic_commande->lines); // Loop on each line of order for ($lig = 0; $lig < $numlines; $lig++) { + $reliquat = $generic_commande->lines[$lig]->qty - $generic_commande->expeditions[$generic_commande->lines[$lig]->id]; + if ($generic_commande->lines[$lig]->product_type == 0 && $generic_commande->lines[$lig]->fk_product > 0) { // If line is a product and not a service $nbprod++; // order contains real products $generic_product->id = $generic_commande->lines[$lig]->fk_product; @@ -1872,15 +1875,15 @@ if ($resql) { $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; } + if ($reliquat > $generic_product->stock_reel) { + $notshippable++; + } if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) { // Default code. Default should be this case. - $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->product_ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25); + $text_info .= $reliquat.' x '.$generic_commande->lines[$lig]->product_ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 20); $text_info .= ' - '.$langs->trans("Stock").': '.$generic_product->stock_reel.''; $text_info .= ' - '.$langs->trans("VirtualStock").': '.$generic_product->stock_theorique.''; + $text_info .= ($reliquat != $generic_commande->lines[$lig]->qty ? ' ('.$langs->trans("QtyInOtherShipments").' '.($generic_commande->lines[$lig]->qty - $reliquat).')' : ''); $text_info .= '
'; - - if ($generic_commande->lines[$lig]->qty > $generic_product->stock_reel) { - $notshippable++; - } } else { // BUGGED CODE. // DOES NOT TAKE INTO ACCOUNT MANUFACTURING. THIS CODE SHOULD BE USELESS. PREVIOUS CODE SEEMS COMPLETE. // COUNT STOCK WHEN WE SHOULD ALREADY HAVE VALUE @@ -1908,32 +1911,31 @@ if ($resql) { $stock_order_supplier = $generic_product->stats_commande_fournisseur['qty']; } } - $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25); + $text_info .= $reliquat.' x '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 20); $text_stock_reel = $generic_product->stock_reel.'/'.$stock_order; if ($stock_order > $generic_product->stock_reel && !($generic_product->stock_reel < $generic_commande->lines[$lig]->qty)) { $warning++; $text_warning .= ''.$langs->trans('Available').' : '.$text_stock_reel.''; } - if ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty) { - $notshippable++; + if ($reliquat > $generic_product->stock_reel) { $text_info .= ''.$langs->trans('Available').' : '.$text_stock_reel.''; } else { $text_info .= ''.$langs->trans('Available').' : '.$text_stock_reel.''; } if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled)) { - $text_info .= ' '.$langs->trans('SupplierOrder').' : '.$stock_order_supplier.'
'; - } else { - $text_info .= '
'; + $text_info .= ' '.$langs->trans('SupplierOrder').' : '.$stock_order_supplier; } + $text_info .= ($reliquat != $generic_commande->lines[$lig]->qty ? ' ('.$langs->trans("QtyInOtherShipments").' '.($generic_commande->lines[$lig]->qty - $reliquat).')' : ''); + $text_info .= '
'; } } } if ($notshippable == 0) { $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'green paddingleft'); - $text_info = $langs->trans('Shippable').'
'.$text_info; + $text_info = $text_icon.' '.$langs->trans('Shippable').'
'.$text_info; } else { $text_icon = img_picto('', 'dolly', '', false, 0, 0, '', 'error paddingleft'); - $text_info = $langs->trans('NonShippable').'
'.$text_info; + $text_info = $text_icon.' '.$langs->trans('NonShippable').'
'.$text_info; } } diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 064dfc3a52c..f835e293f5f 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1126,16 +1126,19 @@ if ($action == 'create') { $product_static->status_buy = $line->product_tobuy; $product_static->status_batch = $line->product_tobatch; + $showdescinproductdesc = (getDolGlobalString('PRODUIT_DESC_IN_FORM') == 2 ? 1 : 0); + $text = $product_static->getNomUrl(1); $text .= ' - '.(!empty($line->label) ? $line->label : $line->product_label); - $description = ($conf->global->PRODUIT_DESC_IN_FORM ? '' : dol_htmlentitiesbr($line->desc)); + $description = ($showdescinproductdesc ? '' : dol_htmlentitiesbr($line->desc)); + print $form->textwithtooltip($text, $description, 3, '', '', $i); // Show range print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end)); // Add description in form - if (!empty($conf->global->PRODUIT_DESC_IN_FORM)) { + if ($showdescinproductdesc) { print ($line->desc && $line->desc != $line->product_label) ? '
'.dol_htmlentitiesbr($line->desc) : ''; } From 38dbaa3d0785174c1dccf686449206979cd26197 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 24 Jan 2022 14:12:27 +0100 Subject: [PATCH 25/26] Doc --- htdocs/install/mysql/migration/15.0.0-16.0.0.sql | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 4ee300998ea..1ef84b065b9 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -38,6 +38,4 @@ UPDATE llx_rights_def SET perms = 'writeall' WHERE perms = 'writeall_advance' AN -- v16 - --- Missing in v14 or lower ALTER TABLE llx_projet_task_time ADD COLUMN fk_product integer NULL; From be01e3b1aca44814fcd5f5f2ac1f755d547b6d25 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 24 Jan 2022 14:48:18 +0100 Subject: [PATCH 26/26] Migration --- htdocs/install/mysql/migration/12.0.0-13.0.0.sql | 6 +++--- htdocs/install/mysql/migration/15.0.0-16.0.0.sql | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index a9f1a669e52..517771ced4e 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -484,9 +484,9 @@ ALTER TABLE llx_delivery DROP FOREIGN KEY fk_livraison_fk_user_author; ALTER TABLE llx_delivery DROP FOREIGN KEY fk_livraison_fk_user_valid; -- add constraint -ALTER TABLE llx_delivery ADD CONSTRAINT fk_delivery_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid); -ALTER TABLE llx_delivery ADD CONSTRAINT fk_delivery_fk_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid); -ALTER TABLE llx_delivery ADD CONSTRAINT fk_delivery_fk_user_valid FOREIGN KEY (fk_user_valid) REFERENCES llx_user (rowid); +ALTER TABLE llx_delivery ADD CONSTRAINT fk_delivery_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid); +ALTER TABLE llx_delivery ADD CONSTRAINT fk_delivery_fk_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid); +ALTER TABLE llx_delivery ADD CONSTRAINT fk_delivery_fk_user_valid FOREIGN KEY (fk_user_valid) REFERENCES llx_user (rowid); ALTER TABLE llx_deliverydet DROP FOREIGN KEY fk_livraisondet_fk_livraison; ALTER TABLE llx_deliverydet DROP INDEX idx_livraisondet_fk_expedition; diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 1ef84b065b9..93eecc6fa89 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -1,7 +1,7 @@ -- -- Be carefull to requests order. -- This file must be loaded by calling /install/index.php page --- when current version is 14.0.0 or higher. +-- when current version is 15.0.0 or higher. -- -- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y -- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y