From 7a12ba9c2006e6680575a4ff40e0ecf8a7fbdbb2 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 24 Mar 2023 15:58:53 +0100 Subject: [PATCH 01/20] FIX missing "multidir_output" for project sharing (Multicompany) --- htdocs/core/lib/files.lib.php | 8 ++++---- htdocs/core/lib/project.lib.php | 4 ++-- htdocs/core/modules/project/doc/pdf_baleine.modules.php | 4 ++-- htdocs/core/modules/project/doc/pdf_beluga.modules.php | 4 ++-- htdocs/core/modules/project/doc/pdf_timespent.modules.php | 4 ++-- htdocs/projet/card.php | 8 ++++---- htdocs/projet/class/task.class.php | 2 ++ htdocs/projet/document.php | 4 ++-- htdocs/projet/tasks/document.php | 2 +- 9 files changed, 21 insertions(+), 19 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 264c12ffb65..9f067f7ada9 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2813,7 +2813,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } $original_file = $conf->commande->multidir_output[$entity].'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."commande WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('order').")"; - } elseif ($modulepart == 'project' && !empty($conf->project->dir_output)) { + } elseif ($modulepart == 'project' && !empty($conf->project->multidir_output[$entity])) { // Wrapping pour les projets if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed = 1; @@ -2825,9 +2825,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $accessallowed = checkUserAccessToObject($user, array('projet'), $tmpproject->id, 'projet&project', '', '', 'rowid', ''); } } - $original_file = $conf->project->dir_output.'/'.$original_file; + $original_file = $conf->project->multidir_output[$entity].'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")"; - } elseif ($modulepart == 'project_task' && !empty($conf->project->dir_output)) { + } elseif ($modulepart == 'project_task' && !empty($conf->project->multidir_output[$entity])) { if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed = 1; // If we known $id of project, call checkUserAccessToObject to check permission on properties and contact of project @@ -2838,7 +2838,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $accessallowed = checkUserAccessToObject($user, array('projet_task'), $tmptask->id, 'projet_task&project', '', '', 'rowid', ''); } } - $original_file = $conf->project->dir_output.'/'.$original_file; + $original_file = $conf->project->multidir_output[$entity].'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")"; } elseif (($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') && !empty($conf->fournisseur->commande->dir_output)) { // Wrapping pour les commandes fournisseurs diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 9d82ed8ead8..390e6d93143 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -275,7 +275,7 @@ function project_prepare_head(Project $project, $moreparam = '') } else { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; - $upload_dir = $conf->project->dir_output."/".dol_sanitizeFileName($project->ref); + $upload_dir = $conf->project->multidir_output[$project->entity]."/".dol_sanitizeFileName($project->ref); $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); $nbLinks = Link::count($db, $project->element, $project->id); $totalAttached = $nbFiles + $nbLinks; @@ -401,7 +401,7 @@ function task_prepare_head($object) } $head[$h][0] = DOL_URL_ROOT.'/projet/tasks/document.php?id='.$object->id.(GETPOST('withproject') ? '&withproject=1' : ''); - $filesdir = $conf->project->dir_output."/".dol_sanitizeFileName($object->project->ref).'/'.dol_sanitizeFileName($object->ref); + $filesdir = $conf->project->multidir_output[$object->entity]."/".dol_sanitizeFileName($object->project->ref).'/'.dol_sanitizeFileName($object->ref); include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; $nbFiles = count(dol_dir_list($filesdir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); diff --git a/htdocs/core/modules/project/doc/pdf_baleine.modules.php b/htdocs/core/modules/project/doc/pdf_baleine.modules.php index df013a2fad0..478c9c5bd82 100644 --- a/htdocs/core/modules/project/doc/pdf_baleine.modules.php +++ b/htdocs/core/modules/project/doc/pdf_baleine.modules.php @@ -195,11 +195,11 @@ class pdf_baleine extends ModelePDFProjects // Load traductions files required by page $outputlangs->loadLangs(array("main", "dict", "companies", "projects")); - if ($conf->project->dir_output) { + if ($conf->project->multidir_output[$object->entity]) { //$nblines = count($object->lines); // This is set later with array of tasks $objectref = dol_sanitizeFileName($object->ref); - $dir = $conf->project->dir_output; + $dir = $conf->project->multidir_output[$object->entity]; if (!preg_match('/specimen/i', $objectref)) { $dir .= "/".$objectref; } diff --git a/htdocs/core/modules/project/doc/pdf_beluga.modules.php b/htdocs/core/modules/project/doc/pdf_beluga.modules.php index fba5e02b098..e5db978e603 100644 --- a/htdocs/core/modules/project/doc/pdf_beluga.modules.php +++ b/htdocs/core/modules/project/doc/pdf_beluga.modules.php @@ -242,11 +242,11 @@ class pdf_beluga extends ModelePDFProjects // Load traductions files required by page $outputlangs->loadLangs(array("main", "dict", "companies", "projects")); - if ($conf->project->dir_output) { + if ($conf->project->multidir_output[$object->entity]) { //$nblines = count($object->lines); // This is set later with array of tasks $objectref = dol_sanitizeFileName($object->ref); - $dir = $conf->project->dir_output; + $dir = $conf->project->multidir_output[$object->entity]; if (!preg_match('/specimen/i', $objectref)) { $dir .= "/".$objectref; } diff --git a/htdocs/core/modules/project/doc/pdf_timespent.modules.php b/htdocs/core/modules/project/doc/pdf_timespent.modules.php index 9d118b2a555..8db0aadf1fd 100644 --- a/htdocs/core/modules/project/doc/pdf_timespent.modules.php +++ b/htdocs/core/modules/project/doc/pdf_timespent.modules.php @@ -195,11 +195,11 @@ class pdf_timespent extends ModelePDFProjects // Load traductions files required by page $outputlangs->loadLangs(array("main", "dict", "companies", "projects")); - if ($conf->project->dir_output) { + if ($conf->project->multidir_output[$object->entity]) { //$nblines = count($object->lines); // This is set later with array of tasks $objectref = dol_sanitizeFileName($object->ref); - $dir = $conf->project->dir_output; + $dir = $conf->project->multidir_output[$object->entity]; if (!preg_match('/specimen/i', $objectref)) { $dir .= "/".$objectref; } diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 7fe1f8f77e0..c107223efd4 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -390,7 +390,7 @@ if (empty($reshook)) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $langs->load("other"); - $upload_dir = $conf->project->dir_output; + $upload_dir = $conf->project->multidir_output[$object->entity]; $file = $upload_dir.'/'.GETPOST('file'); $ret = dol_delete_file($file, 0, 0, 0, $object); if ($ret) { @@ -1402,12 +1402,12 @@ if ($action == 'create' && $user->rights->projet->creer) { * Generated documents */ $filename = dol_sanitizeFileName($object->ref); - $filedir = $conf->project->dir_output."/".dol_sanitizeFileName($object->ref); + $filedir = $conf->project->multidir_output[$object->entity]."/".dol_sanitizeFileName($object->ref); $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; $genallowed = ($user->rights->projet->lire && $userAccess > 0); $delallowed = ($user->rights->projet->creer && $userWrite > 0); - print $formfile->showdocuments('project', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf); + print $formfile->showdocuments('project', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 0, 0, '', '', '', '', '', $object); print '
'; @@ -1426,7 +1426,7 @@ if ($action == 'create' && $user->rights->projet->creer) { // Presend form $modelmail = 'project'; $defaulttopic = 'SendProjectRef'; - $diroutput = $conf->project->dir_output; + $diroutput = $conf->project->multidir_output[$object->entity]; $autocopy = 'MAIN_MAIL_AUTOCOPY_PROJECT_TO'; // used to know the automatic BCC to add $trackid = 'proj'.$object->id; diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 7ff5d651fed..87dab1c728a 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -274,6 +274,7 @@ class Task extends CommonObjectLine $sql = "SELECT"; $sql .= " t.rowid,"; $sql .= " t.ref,"; + $sql .= " t.entity,"; $sql .= " t.fk_projet as fk_project,"; $sql .= " t.fk_task_parent,"; $sql .= " t.label,"; @@ -318,6 +319,7 @@ class Task extends CommonObjectLine $this->id = $obj->rowid; $this->ref = $obj->ref; + $this->entity = $obj->entity; $this->fk_project = $obj->fk_project; $this->fk_task_parent = $obj->fk_task_parent; $this->label = $obj->label; diff --git a/htdocs/projet/document.php b/htdocs/projet/document.php index 588043a56dc..660e4101e19 100644 --- a/htdocs/projet/document.php +++ b/htdocs/projet/document.php @@ -49,7 +49,7 @@ if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT) && method_exists($ob } if ($id > 0 || !empty($ref)) { - $upload_dir = $conf->project->dir_output."/".dol_sanitizeFileName($object->ref); + $upload_dir = $conf->project->multidir_output[$object->entity]."/".dol_sanitizeFileName($object->ref); } // Get parameters @@ -109,7 +109,7 @@ llxHeader('', $title, $help_url); $form = new Form($db); if ($object->id > 0) { - $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref); + $upload_dir = $conf->project->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref); // To verify role of users //$userAccess = $object->restrictedProjectArea($user,'read'); diff --git a/htdocs/projet/tasks/document.php b/htdocs/projet/tasks/document.php index 3ef93529b64..071516d85eb 100644 --- a/htdocs/projet/tasks/document.php +++ b/htdocs/projet/tasks/document.php @@ -110,7 +110,7 @@ if ($id > 0 || !empty($ref)) { $object->project = clone $projectstatic; - $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($projectstatic->ref).'/'.dol_sanitizeFileName($object->ref); + $upload_dir = $conf->project->multidir_output[$projectstatic->entity].'/'.dol_sanitizeFileName($projectstatic->ref).'/'.dol_sanitizeFileName($object->ref); } include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; From 4240ac18f37edba951519384a05e5ba5b7a3bdcd Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 24 Mar 2023 16:18:14 +0100 Subject: [PATCH 02/20] FIX task have the same entity of project --- htdocs/projet/class/task.class.php | 2 +- htdocs/projet/tasks.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 87dab1c728a..1ece3dc712f 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -198,7 +198,7 @@ class Task extends CommonObjectLine $sql .= ", progress"; $sql .= ", budget_amount"; $sql .= ") VALUES ("; - $sql .= ((int) $conf->entity); + $sql .= (!empty($this->entity) ? (int) $this->entity : (int) $conf->entity); $sql .= ", ".((int) $this->fk_project); $sql .= ", ".(!empty($this->ref) ? "'".$this->db->escape($this->ref)."'" : 'null'); $sql .= ", ".((int) $this->fk_task_parent); diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 22258bd3b18..e5a7bb4134a 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -336,6 +336,7 @@ if ($action == 'createtask' && $user->rights->projet->creer) { $task = new Task($db); $task->fk_project = $projectid; + $task->entity = $object->entity; // Task have the same entity of project $task->ref = $taskref; $task->label = $label; $task->description = $description; From b9aeadf566b11fb8a3bd89767169cd1ea0c9296c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 24 Mar 2023 17:30:00 +0100 Subject: [PATCH 03/20] FIX avoid phpunit error --- htdocs/projet/class/project.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index cb0fac8ca02..17f9e9b1f16 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1347,6 +1347,7 @@ class Project extends CommonObject // Initialise parameters $this->id = 0; $this->ref = 'SPECIMEN'; + $this->entity = $conf->entity; $this->specimen = 1; $this->socid = 1; $this->date_c = $now; From 538a6870f1f2dbe926a0a3db2120fee042ae9160 Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Wed, 29 Mar 2023 11:00:20 +0200 Subject: [PATCH 04/20] FIX : it was not possible to update extrafields of expedition lines with batch without editing batch value --- htdocs/expedition/card.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 8aa54ca8904..4ff1614f26f 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -581,6 +581,7 @@ if (empty($reshook)) { $num_prod = count($lines); for ($i = 0; $i < $num_prod; $i++) { if ($lines[$i]->id == $line_id) { // we have found line to update + $update_done = false; $line = new ExpeditionLigne($db); $line->fk_expedition = $object->id; @@ -621,6 +622,8 @@ if (empty($reshook)) { if ($line->update($user) < 0) { setEventMessages($line->error, $line->errors, 'errors'); $error++; + } else { + $update_done=true; } } else { setEventMessages($lotStock->error, $lotStock->errors, 'errors'); @@ -663,6 +666,8 @@ if (empty($reshook)) { if ($line->update($user) < 0) { setEventMessages($line->error, $line->errors, 'errors'); $error++; + } else { + $update_done=true; } } else { setEventMessages($line->error, $line->errors, 'errors'); @@ -680,6 +685,8 @@ if (empty($reshook)) { if ($object->create_line_batch($line, $line->array_options) < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; + } else { + $update_done=true; } } } else { @@ -717,6 +724,8 @@ if (empty($reshook)) { if ($line->update($user) < 0) { setEventMessages($line->error, $line->errors, 'errors'); $error++; + } else { + $update_done=true; } } unset($_POST[$stockLocation]); @@ -731,6 +740,8 @@ if (empty($reshook)) { if ($line->update($user) < 0) { setEventMessages($line->error, $line->errors, 'errors'); $error++; + } else { + $update_done=true; } unset($_POST[$qty]); } @@ -743,10 +754,18 @@ if (empty($reshook)) { if ($line->update($user) < 0) { setEventMessages($line->error, $line->errors, 'errors'); $error++; + } else { + $update_done=true; } unset($_POST[$qty]); } } + + if(empty($update_done)) { + $line->id = $lines[$i]->id; + $line->insertExtraFields(); + } + } } From cb63bbba325b46dd63de9b4af3c28b7f107d1a4e Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 29 Mar 2023 09:06:53 +0000 Subject: [PATCH 05/20] Fixing style errors. --- htdocs/expedition/card.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 4ff1614f26f..e2220ec6367 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -761,11 +761,10 @@ if (empty($reshook)) { } } - if(empty($update_done)) { + if (empty($update_done)) { $line->id = $lines[$i]->id; $line->insertExtraFields(); } - } } From 3fdec7cecf647a21af9997eb6c72a199872131a9 Mon Sep 17 00:00:00 2001 From: atm-lena Date: Fri, 31 Mar 2023 15:36:16 +0200 Subject: [PATCH 06/20] FIX - PDF Espadon => display extrafields --- .../modules/expedition/doc/pdf_espadon.modules.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php index 12f20d74d7e..9a1cac5fecc 100644 --- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php @@ -394,20 +394,20 @@ class pdf_espadon extends ModelePdfExpedition $label .= $object->tracking_url; } - $height_trackingnumber += 6; + $height_trackingnumber += 4; $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->writeHTMLCell(60, $height_trackingnumber, $this->posxdesc - 1, $tab_top_alt, $label, 0, 1, false, true, 'L'); - $tab_top = $pdf->GetY(); } } + $tab_top = $pdf->GetY(); } // Notes $pagenb = $pdf->getPage(); if (!empty($notetoshow) || !empty($object->tracking_number)) { - $tab_top -= 2; + $tab_top -= 1; $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite; $pageposbeforenote = $pagenb; @@ -476,7 +476,7 @@ class pdf_espadon extends ModelePdfExpedition $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter) + $height_trackingnumber + 1; $tab_top_newpage = $tab_topbeforetrackingnumber; } - $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); + $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 2); } else { if (empty($height_trackingnumber)) { $height_note = $this->page_hauteur - ($tab_top + $heightforfooter); @@ -484,7 +484,7 @@ class pdf_espadon extends ModelePdfExpedition $height_note = $this->page_hauteur - ($tab_top + $heightforfooter)+ $height_trackingnumber + 1; $tab_top = $tab_topbeforetrackingnumber; } - $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); + $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 2); } // Add footer @@ -510,7 +510,7 @@ class pdf_espadon extends ModelePdfExpedition $height_note = $posyafter - $tab_top + $height_trackingnumber + 1; $tab_top = $tab_topbeforetrackingnumber; } - $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); + $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 2); if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { From 9ec5bd6fc7d9f41549834a9e21aca93b86a208f5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2023 09:49:27 +0200 Subject: [PATCH 07/20] Prepare 17.0.1 --- ChangeLog | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3f193d9902b..07fa52ed00f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,7 +5,56 @@ English Dolibarr ChangeLog ***** ChangeLog for 17.0.1 compared to 17.0.0 ***** -TODO +FIX: 17.0 PHP Warning invalid argument supplied for foreach +FIX: #[23799] - External users are not able to create events - correction +FIX: #23966 Error "Param dbt_keyfield is required but not defined +FIX: #24138 Fix box_birthdays SQL for postgres +FIX: #24201 Upload of external module fails to copy from incorrectly generated temp source dir +FIX: #24240 Dolibarr V17.0.0 PHP8 fatal error +FIX: accountancy lettering: better error management +FIX: accountancy lettering: correctly calculated number of lettering operations done +FIX: accountancy lettering: error management and prevention +FIX: accountancy lettering: prevent null results when fetching link with payments +FIX: action delete card fac rec +FIX: Add bookmark with search fields that are arrays (backport 4157263cb898f1847cfcfc22dee6007c01b13a4d) +FIX: Add missing hook on LibStatut +FIX: Add more context for selectForFormsListWhere Hook +FIX: Autofill / clear qty in inventory page +FIX: avoid php8 warnings +FIX: avoid phpunit error +FIX: can not show all csv fields (a reason for that ?) +FIX: change date on select date input when prefix is used +FIX: dol_textishtml() function +FIX: expense report accountancy: sql syntax error when performing automatic linking +FIX: Extrafields in Notes to unify with orders or invoices. +FIX: fatal error when margin enable (missing check on element), fix User::hasRight() when checking a margin right +FIX: feedbacks +FIX: FILTER_VALIDATE_EMAIL param is not a string +FIX: #24298 No error or 0.00 instead of NULL in database anymore when emptying an extrafield of type price on a propal card +FIX: full group by handle +FIX: holiday counter massaction: ErrorBadValueForParamNotAString and PHP 8 warning when no approval user right +FIX: installation superadmin creation: PHP 8 warning +FIX: invoices order on sells journal +FIX: it was not possible to update extrafields of expedition lines with batch without editing batch value +FIX: limit after order in get objects in category +FIX: method dolGetGlobalString not defined with saphir +FIX: missing column default workstation +FIX: missing drop foreign key before modify field +FIX: missing "multidir_output" for project sharing (Multicompany) +FIX: missing protection on ajax public ticket page for valid email +FIX: ODT management inverted between purchase invoice and order +FIX: PDF Espadon => display extrafields +FIX: PDF Espadon Expedition : notes and tracking number +FIX: Phpunit Rename WebsiteTest.class.php to WebsiteTest.php +FIX: project referent elements list: conf to hide tasks was flipped +FIX: Protection on agenda view for a thirdparty id that does not exist +FIX: search_project_user +FIX: societe list: regression to redirection to customer card when single result of search filters +FIX: SQL error "unknown column p.fk_soc" because ANSI-92 joins take precedence over ANSI-89 joins +FIX: task have the same entity of project +FIX: token error when closing ticket from public interface +FIX: Warning on purchase order + Property fk_commande not defined + ***** ChangeLog for 17.0.0 compared to 16.0.0 ***** From 7096f0c23691a8e9118667a7ea9b9e9bd593b345 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Apr 2023 23:23:51 +0200 Subject: [PATCH 08/20] Fix css --- htdocs/core/tpl/passwordforgotten.tpl.php | 6 ++++-- htdocs/core/tpl/passwordreset.tpl.php | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/htdocs/core/tpl/passwordforgotten.tpl.php b/htdocs/core/tpl/passwordforgotten.tpl.php index 27ab617636b..5b418f63541 100644 --- a/htdocs/core/tpl/passwordforgotten.tpl.php +++ b/htdocs/core/tpl/passwordforgotten.tpl.php @@ -238,21 +238,23 @@ if (!empty($morelogincontent)) { -'; } } else { + print ''; } ?> -

diff --git a/htdocs/core/tpl/passwordreset.tpl.php b/htdocs/core/tpl/passwordreset.tpl.php index e1368c0d3ee..32500cc38ab 100644 --- a/htdocs/core/tpl/passwordreset.tpl.php +++ b/htdocs/core/tpl/passwordreset.tpl.php @@ -117,7 +117,7 @@ if ($setnewpassword && $username && $passworduidhash) { ?> - + global->MAIN_LOGIN_BACKGROUND) ? '' : ' style="background-size: cover; background-position: center center; background-attachment: fixed; background-repeat: no-repeat; background-image: url(\''.DOL_URL_ROOT.'/viewimage.php?cache=1&noalt=1&modulepart=mycompany&file='.urlencode('logos/'.$conf->global->MAIN_LOGIN_BACKGROUND).'\')"'; ?>> @@ -278,21 +278,23 @@ if (!empty($morelogincontent)) { -
global->MAIN_LOGIN_BACKGROUND) ? '' : ' backgroundsemitransparent boxshadow').'" style="max-width: 70%">'; print ''; print $langs->trans('EnterNewPasswordHere'); print ''; + print '
'; } } else { + print '
'; print '
'; print $langs->trans('AuthenticationDoesNotAllowSendNewPassword', $mode); print '
'; + print '
'; } ?> -
From d7dff81b8fdcc82625437682d59e01ef1d41616c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 00:52:09 +0200 Subject: [PATCH 09/20] Debug emailcollector --- .../class/emailcollector.class.php | 53 ++++++++++++++----- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 46a73e38b36..76a934d97ac 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -935,13 +935,13 @@ class EmailCollector extends CommonObject if (preg_match('/'.$regexstring.'/'.$regexoptions, $sourcestring, $regforval)) { // Overwrite param $tmpproperty $valueextracted = isset($regforval[count($regforval) - 1]) ?trim($regforval[count($regforval) - 1]) : null; - if (strtolower($sourcefield) == 'header') { + if (strtolower($sourcefield) == 'header') { // extract from HEADER if (preg_match('/^options_/', $tmpproperty)) { $object->array_options[preg_replace('/^options_/', '', $tmpproperty)] = $this->decodeSMTPSubject($valueextracted); } else { $object->$tmpproperty = $this->decodeSMTPSubject($valueextracted); } - } else { + } else { // extract from BODY if (preg_match('/^options_/', $tmpproperty)) { $object->array_options[preg_replace('/^options_/', '', $tmpproperty)] = $this->decodeSMTPSubject($valueextracted); } else { @@ -1683,8 +1683,12 @@ class EmailCollector extends CommonObject //print $messagetext; //exit; + $fromstring = ''; + $replytostring = ''; + if (!empty($conf->global->MAIN_IMAP_USE_PHPIMAP)) { $fromstring = $overview['from']; + //$replytostring = empty($overview['reply-to']) ? '' : $overview['reply-to']; $sender = $overview['sender']; $to = $overview['to']; @@ -1695,6 +1699,7 @@ class EmailCollector extends CommonObject $subject = $overview['subject']; } else { $fromstring = $overview[0]->from; + //$replytostring = empty($overview[0]->replyto) ? '' : $overview[0]->replyto; $sender = $overview[0]->sender; $to = $overview[0]->to; @@ -1715,6 +1720,13 @@ class EmailCollector extends CommonObject $from = $fromstring; $fromtext = ''; } + if (preg_match('/^(.*)<(.*)>$/', $replytostring, $reg)) { + $replyto = $reg[2]; + $replytotext = $reg[1]; + } else { + $replyto = $replytostring; + $replytotext = ''; + } $fk_element_id = 0; $fk_element_type = ''; @@ -2011,6 +2023,7 @@ class EmailCollector extends CommonObject $idtouseforthirdparty = ''; $nametouseforthirdparty = ''; $emailtouseforthirdparty = ''; + $namealiastouseforthirdparty = ''; // $actionparam = 'param=SET:aaa' or 'param=EXTRACT:BODY:....' $arrayvaluetouse = dolExplodeIntoArray($actionparam, ';', '='); @@ -2048,16 +2061,23 @@ class EmailCollector extends CommonObject $emailtouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> Found propertytooverwrite='.dol_escape_htmltag($propertytooverwrite); - } else { + } elseif ($propertytooverwrite == 'name') { $nametouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> Found nametouseforthirdparty='.dol_escape_htmltag($nametouseforthirdparty); + } elseif ($propertytooverwrite == 'name_alias') { + $nametouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; + + $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> Found namealiastouseforthirdparty='.dol_escape_htmltag($namealiastouseforthirdparty); + } else { + $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> We discard this, not used to search existing thirdparty'; } } else { // Regex not found $idtouseforthirdparty = null; $nametouseforthirdparty = null; $emailtouseforthirdparty = null; + $namealiastouseforthirdparty = null; $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> Not found'; } @@ -2071,6 +2091,7 @@ class EmailCollector extends CommonObject } elseif (preg_match('/^(SET|SETIFEMPTY):(.*)$/', $valueforproperty, $reg)) { //if (preg_match('/^options_/', $tmpproperty)) $object->array_options[preg_replace('/^options_/', '', $tmpproperty)] = $reg[1]; //else $object->$tmpproperty = $reg[1]; + // Example: id=SETIFEMPTY:123 if ($propertytooverwrite == 'id') { $idtouseforthirdparty = $reg[2]; @@ -2079,10 +2100,14 @@ class EmailCollector extends CommonObject $emailtouseforthirdparty = $reg[2]; $operationslog .= '
We set property emailtouseforthrdparty='.dol_escape_htmltag($emailtouseforthirdparty); - } else { + } elseif ($propertytooverwrite == 'name') { $nametouseforthirdparty = $reg[2]; $operationslog .= '
We set property nametouseforthirdparty='.dol_escape_htmltag($nametouseforthirdparty); + } elseif ($propertytooverwrite == 'name_alias') { + $namealiastouseforthirdparty = $reg[2]; + + $operationslog .= '
We set property namealiastouseforthirdparty='.dol_escape_htmltag($namealiastouseforthirdparty); } } else { $errorforactions++; @@ -2092,8 +2117,8 @@ class EmailCollector extends CommonObject } } - if (!$errorforactions && ($idtouseforthirdparty || $emailtouseforthirdparty || $nametouseforthirdparty)) { - $result = $thirdpartystatic->fetch($idtouseforthirdparty, $nametouseforthirdparty, '', '', '', '', '', '', '', '', $emailtouseforthirdparty); + if (!$errorforactions && ($idtouseforthirdparty || $emailtouseforthirdparty || $nametouseforthirdparty || $namealiastouseforthirdparty)) { + $result = $thirdpartystatic->fetch($idtouseforthirdparty, $nametouseforthirdparty, '', '', '', '', '', '', '', '', $emailtouseforthirdparty, $namealiastouseforthirdparty); if ($result < 0) { $errorforactions++; $this->error = 'Error when getting thirdparty with name '.$nametouseforthirdparty.' (may be 2 record exists with same name ?)'; @@ -2101,21 +2126,25 @@ class EmailCollector extends CommonObject break; } elseif ($result == 0) { if ($operation['type'] == 'loadthirdparty') { - dol_syslog("Third party with id=".$idtouseforthirdparty." email=".$emailtouseforthirdparty." name=".$nametouseforthirdparty." was not found"); + dol_syslog("Third party with id=".$idtouseforthirdparty." email=".$emailtouseforthirdparty." name=".$nametouseforthirdparty." name_alias=".$namealiastouseforthirdparty." was not found"); $errorforactions++; $langs->load("errors"); - $this->error = $langs->trans('ErrorFailedToLoadThirdParty', $idtouseforthirdparty, $emailtouseforthirdparty, $nametouseforthirdparty); + $this->error = $langs->trans('ErrorFailedToLoadThirdParty', $idtouseforthirdparty, $emailtouseforthirdparty, $nametouseforthirdparty, $namealiastouseforthirdparty); $this->errors[] = $this->error; } elseif ($operation['type'] == 'loadandcreatethirdparty') { - dol_syslog("Third party with id=".$idtouseforthirdparty." email=".$emailtouseforthirdparty." name=".$nametouseforthirdparty." was not found. We try to create it."); + dol_syslog("Third party with id=".$idtouseforthirdparty." email=".$emailtouseforthirdparty." name=".$nametouseforthirdparty." name_alias=".$namealiastouseforthirdparty." was not found. We try to create it."); // Create thirdparty $thirdpartystatic->name = $nametouseforthirdparty; - if ($fromtext != $nametouseforthirdparty) { - $thirdpartystatic->name_alias = $fromtext; + if (!empty($namealiastouseforthirdparty)) { + if ($namealiastouseforthirdparty != $nametouseforthirdparty) { + $thirdpartystatic->name_alias = $namealiastouseforthirdparty; + } + } else { + $thirdpartystatic->name_alias = (empty($replytostring) ? (empty($fromtext) ? '': $fromtext) : $replytostring); } - $thirdpartystatic->email = ($emailtouseforthirdparty ? $emailtouseforthirdparty : $from); + $thirdpartystatic->email = (empty($emailtouseforthirdparty) ? (empty($replyto) ? (empty($from) ? '' : $from) : $replyto) : $emailtouseforthirdparty); // Overwrite values with values extracted from source email $errorforthisaction = $this->overwritePropertiesOfObject($thirdpartystatic, $operation['actionparam'], $messagetext, $subject, $header, $operationslog); From c4d7b15906da94888ef59bb75cef70aa08b622b3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 00:57:18 +0200 Subject: [PATCH 10/20] Fix trans --- htdocs/langs/en_US/admin.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 9d5be55baa6..1503bfbd5c4 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2196,7 +2196,7 @@ LargerThan=Larger than IfTrackingIDFoundEventWillBeLinked=Note that If a tracking ID of an object is found into email, or if the email is an answer of an email aready collected and linked to an object, the created event will be automatically linked to the known related object. WithGMailYouCanCreateADedicatedPassword=With a GMail account, if you enabled the 2 steps validation, it is recommanded to create a dedicated second password for the application instead of using your own account passsword from https://myaccount.google.com/. EmailCollectorTargetDir=It may be a desired behaviour to move the email into another tag/directory when it was processed successfully. Just set name of directory here to use this feature (Do NOT use special characters in name). Note that you must also use a read/write login account. -EmailCollectorLoadThirdPartyHelp=You can use this action to use the email content to find and load an existing thirdparty in your database. The found (or created) thirdparty will be used for following actions that need it.
For example, if you want to create a thirdparty with a name extracted from a string 'Name: name to find' present into the body, use the sender email as email, you can set the parameter field like this:
'email=HEADER:^From:(.*);name=EXTRACT:BODY:Name:\\s([^\\s]*);client=SET:2;'
+EmailCollectorLoadThirdPartyHelp=You can use this action to use the email content to find and load an existing thirdparty in your database (search will be done on the defined property among 'id','name','name_alias','email'). The found (or created) thirdparty will be used for following actions that need it.
For example, if you want to create a thirdparty with a name extracted from a string 'Name: name to find' present into the body, use the sender email as email, you can set the parameter field like this:
'email=HEADER:^From:(.*);name=EXTRACT:BODY:Name:\\s([^\\s]*);client=SET:2;'
EndPointFor=End point for %s : %s DeleteEmailCollector=Delete email collector ConfirmDeleteEmailCollector=Are you sure you want to delete this email collector? From 5ac9ca5efc230f94ad6aca93016f40137a753a60 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 01:13:13 +0200 Subject: [PATCH 11/20] Fix logs --- .../emailcollector/class/emailcollector.class.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 76a934d97ac..d828e5d3ea0 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1495,7 +1495,7 @@ class EmailCollector extends CommonObject $emailto = $this->decodeSMTPSubject($overview[0]->to); - $operationslog .= '
Process email '.dol_escape_htmltag($iforemailloop)." - References: ".dol_escape_htmltag($headers['References'])." - Subject: ".dol_escape_htmltag($headers['Subject']); + $operationslog .= '
** Process email '.dol_escape_htmltag($iforemailloop)." - References: ".dol_escape_htmltag($headers['References'])." - Subject: ".dol_escape_htmltag($headers['Subject']); dol_syslog("** Process email ".$iforemailloop." References: ".$headers['References']." Subject: ".$headers['Subject']); @@ -2056,21 +2056,21 @@ class EmailCollector extends CommonObject if ($propertytooverwrite == 'id') { $idtouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; - $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> Found idtouseforthirdparty='.dol_escape_htmltag($idtouseforthirdparty); + $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtoupper($sourcefield).' -> Found idtouseforthirdparty='.dol_escape_htmltag($idtouseforthirdparty); } elseif ($propertytooverwrite == 'email') { $emailtouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; - $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> Found propertytooverwrite='.dol_escape_htmltag($propertytooverwrite); + $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtoupper($sourcefield).' -> Found emailtouseforthirdparty='.dol_escape_htmltag($propertytooverwrite); } elseif ($propertytooverwrite == 'name') { $nametouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; - $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> Found nametouseforthirdparty='.dol_escape_htmltag($nametouseforthirdparty); + $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtoupper($sourcefield).' -> Found nametouseforthirdparty='.dol_escape_htmltag($nametouseforthirdparty); } elseif ($propertytooverwrite == 'name_alias') { $nametouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; - $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> Found namealiastouseforthirdparty='.dol_escape_htmltag($namealiastouseforthirdparty); + $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtoupper($sourcefield).' -> Found namealiastouseforthirdparty='.dol_escape_htmltag($namealiastouseforthirdparty); } else { - $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> We discard this, not used to search existing thirdparty'; + $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtoupper($sourcefield).' -> We discard this, not used to search existing thirdparty'; } } else { // Regex not found @@ -2079,7 +2079,7 @@ class EmailCollector extends CommonObject $emailtouseforthirdparty = null; $namealiastouseforthirdparty = null; - $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtolower($sourcefield).' -> Not found'; + $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtoupper($sourcefield).' -> Not found'; } //var_dump($object->$tmpproperty);exit; } else { From 9e4e49bd77e7b020337e484de84e05095b13c893 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 01:16:50 +0200 Subject: [PATCH 12/20] Fix log --- htdocs/emailcollector/class/emailcollector.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index d828e5d3ea0..af3529aa9ad 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -2060,7 +2060,7 @@ class EmailCollector extends CommonObject } elseif ($propertytooverwrite == 'email') { $emailtouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; - $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtoupper($sourcefield).' -> Found emailtouseforthirdparty='.dol_escape_htmltag($propertytooverwrite); + $operationslog .= '
Regex /'.dol_escape_htmltag($regexstring).'/ms into '.strtoupper($sourcefield).' -> Found emailtouseforthirdparty='.dol_escape_htmltag($emailtouseforthirdparty); } elseif ($propertytooverwrite == 'name') { $nametouseforthirdparty = isset($regforval[count($regforval) - 1]) ? trim($regforval[count($regforval) - 1]) : null; From e1bbce7ab708c0a14fdc0a44f568fc29025462b2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 01:21:10 +0200 Subject: [PATCH 13/20] css --- htdocs/admin/emailcollector_card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 23ccea552e1..28e1d4ad285 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -685,11 +685,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; - print '

'; + print '


'; // Operations - print '
'; - print ''; + print '
'; + print '
'; print ''; print ''; print ''; From b4143d3d2cc5995445ab34bf06958ed15f679955 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 01:25:22 +0200 Subject: [PATCH 14/20] Fix tooltip --- htdocs/admin/emailcollector_card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 28e1d4ad285..956a1997319 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -695,8 +695,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; $arrayoftypes = array( - 'loadthirdparty' => $langs->trans('LoadThirdPartyFromName', $langs->transnoentities("ThirdPartyName")), - 'loadandcreatethirdparty' => $langs->trans('LoadThirdPartyFromNameOrCreate', $langs->transnoentities("ThirdPartyName")), + 'loadthirdparty' => $langs->trans('LoadThirdPartyFromName', $langs->transnoentities("ThirdPartyName").'/'.$langs->transnoentities("AliasNameShort").'/'.$langs->transnoentities("Email").'/'.$langs->transnoentities("ID")), + 'loadandcreatethirdparty' => $langs->trans('LoadThirdPartyFromNameOrCreate', $langs->transnoentities("ThirdPartyName").'/'.$langs->transnoentities("AliasNameShort").'/'.$langs->transnoentities("Email").'/'.$langs->transnoentities("ID")), 'recordjoinpiece' => 'AttachJoinedDocumentsToObject', 'recordevent' => 'RecordEvent' ); From 39fa93486d98764fb1f21ca17c06d9f5c7f93b06 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 01:56:44 +0200 Subject: [PATCH 15/20] Debug v17 --- htdocs/projet/card.php | 13 ++----------- htdocs/projet/contact.php | 38 ++++++++++++++++++-------------------- 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 8e6a9fd6881..7fddc12b7c9 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -1213,8 +1213,8 @@ if ($action == 'create' && $user->rights->projet->creer) { $morehtmlref = '
'; // Title $morehtmlref .= dol_escape_htmltag($object->title); - // Thirdparty $morehtmlref .= '
'; + // Thirdparty if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) { $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project'); } @@ -1232,7 +1232,7 @@ if ($action == 'create' && $user->rights->projet->creer) { print '
'; print '
'; - print '
'.img_picto('', 'technic', 'class="pictofixedwidth"').$form->textwithpicto($langs->trans("EmailcollectorOperations"), $langs->trans("EmailcollectorOperationsDesc")).'
'; + print '
'; // Usage if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) { @@ -1302,15 +1302,6 @@ if ($action == 'create' && $user->rights->projet->creer) { } } print ''; - - // Opportunity Weighted Amount - /* - print ''; - */ } // Budget diff --git a/htdocs/projet/contact.php b/htdocs/projet/contact.php index 2174a02c347..21b71b53ac9 100644 --- a/htdocs/projet/contact.php +++ b/htdocs/projet/contact.php @@ -240,6 +240,10 @@ if (($action == 'deleteline' || $action == 'deletecontact') && $user->rights->pr * View */ +$form = new Form($db); +$contactstatic = new Contact($db); +$userstatic = new User($db); + $title = $langs->trans('ProjectContact').' - '.$object->ref.' '.$object->name; if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) { $title = $object->ref.' '.$object->name.' - '.$langs->trans('ProjectContact'); @@ -249,18 +253,12 @@ $help_url = 'EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos|DE: llxHeader('', $title, $help_url); -$form = new Form($db); -$contactstatic = new Contact($db); -$userstatic = new User($db); -/* *************************************************************************** */ -/* */ -/* Edition and view mode */ -/* */ -/* *************************************************************************** */ - if ($id > 0 || !empty($ref)) { + /* + * View + */ if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT) && method_exists($object, 'fetchComments') && empty($object->comments)) { $object->fetchComments(); } @@ -293,10 +291,11 @@ if ($id > 0 || !empty($ref)) { $morehtmlref = '
'; // Title - $morehtmlref .= $object->title; + $morehtmlref .= dol_escape_htmltag($object->title); + $morehtmlref .= '
'; // Thirdparty if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) { - $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1, 'project'); + $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project'); } $morehtmlref .= '
'; @@ -358,26 +357,25 @@ if ($id > 0 || !empty($ref)) { } print ''; - if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) && $object->opp_status) { + if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) && !empty($object->usage_opportunity)) { // Opportunity status print ''; // Opportunity percent - print ''; + print ''; // Opportunity Amount print ''; @@ -397,7 +395,7 @@ if ($id > 0 || !empty($ref)) { $start = dol_print_date($object->date_start, 'day'); print ($start ? $start : '?'); $end = dol_print_date($object->date_end, 'day'); - print ' - '; + print ' - '; print ($end ? $end : '?'); if ($object->hasDelay()) { print img_warning("Late"); @@ -418,7 +416,7 @@ if ($id > 0 || !empty($ref)) { // Description print ''; // Categories From 454372bb4e8a712f4c6143e4837952b8acff3fca Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 02:05:05 +0200 Subject: [PATCH 16/20] Fix show description of project --- htdocs/eventorganization/conferenceorbooth_list.php | 2 +- htdocs/projet/element.php | 2 +- htdocs/projet/tasks.php | 2 +- htdocs/projet/tasks/time.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index 1f31690052f..391f02d7c8c 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -403,7 +403,7 @@ if ($projectid > 0) { // Description print ''; // Categories diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 1bdefbcc1e6..1b002ba5688 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -340,7 +340,7 @@ print '
'.$langs->trans('OpportunityWeightedAmount').''; - if (strcmp($object->opp_amount, '') && strcmp($object->opp_percent, '')) { - print ''.price($object->opp_amount * $object->opp_percent / 100, 0, $langs, 1, 0, -1, $conf->currency).''; - } - print '
'.$langs->trans("OpportunityStatus").''; $code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code'); if ($code) { print $langs->trans("OppStatus".$code); } - print '
'.$langs->trans("OpportunityProbability").''; + print ' / '; if (strcmp($object->opp_percent, '')) { - print price($object->opp_percent, '', $langs, 1, 0).' %'; + print price($object->opp_percent, 0, $langs, 1, 0).' %'; } - print '
'.$langs->trans("OpportunityAmount").''; if (strcmp($object->opp_amount, '')) { - print ''.price($object->opp_amount, '', $langs, 0, 0, 0, $conf->currency).''; + print ''.price($object->opp_amount, 0, $langs, 1, 0, -1, $conf->currency).''; if (strcmp($object->opp_percent, '')) { print '       '.$langs->trans("Weighted").': '.price($object->opp_amount * $object->opp_percent / 100, 0, $langs, 1, 0, -1, $conf->currency).''; } @@ -388,7 +386,7 @@ if ($id > 0 || !empty($ref)) { // Budget print '
'.$langs->trans("Budget").''; if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) { - print ''.price($object->budget_amount, '', $langs, 0, 0, 0, $conf->currency).''; + print ''.price($object->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).''; } print '
'.$langs->trans("Description").''; - print nl2br($object->description); + print dol_htmlentitiesbr($object->description); print '
'.$langs->trans("Description").''; - print nl2br($project->description); + print dol_htmlentitiesbr($project->description); print '
'; // Description print ''; // Categories diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 2ba3f329ac2..f15d5f019ba 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -648,7 +648,7 @@ if ($id > 0 || !empty($ref)) { // Description print ''; // Categories diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index d97dee9a11b..b98e9298732 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1038,7 +1038,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Description print ''; // Categories From b48b980a5a62c6cf502ac26c1facb9871ccf2aeb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 12:59:02 +0200 Subject: [PATCH 17/20] FIX Back to cancel on reception creation --- htdocs/fourn/commande/dispatch.php | 1 + htdocs/reception/card.php | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index f5a983ac5bb..76441dafd0e 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -1069,6 +1069,7 @@ if ($id > 0 || !empty($ref)) { $dispatchBt = empty($conf->reception->enabled) ? $langs->trans("Receive") : $langs->trans("CreateReception"); print '
'; + print ''; print 'global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); @@ -178,7 +180,29 @@ if ($reshook < 0) { } if (empty($reshook)) { + /* + $backurlforlist = DOL_URL_ROOT.'/reception/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + */ + if ($cancel) { + if (!empty($backtopageforcancel)) { + header("Location: ".$backtopageforcancel); + exit; + } elseif (!empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + $action = ''; } @@ -760,6 +784,8 @@ if ($action == 'create') { print ''; print ''; print ''; + print ''; + print ''; if (GETPOST('entrepot_id', 'int')) { print ''; } From 3e77a6cbd43c11f69cf29266ccbfc3ae805eb552 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 18:42:55 +0200 Subject: [PATCH 18/20] FIX Reception process loose some lines on first error. --- htdocs/fourn/js/lib_dispatch.js.php | 4 +- htdocs/reception/card.php | 72 ++++++++++++++++++----------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/htdocs/fourn/js/lib_dispatch.js.php b/htdocs/fourn/js/lib_dispatch.js.php index 01af2ee5d91..ff822543ddb 100644 --- a/htdocs/fourn/js/lib_dispatch.js.php +++ b/htdocs/fourn/js/lib_dispatch.js.php @@ -93,8 +93,8 @@ function addDispatchLine(index, type, mode) } console.log("qtyDispatched="+qtyDispatched+" qtyOrdered="+qtyOrdered); - if (qtyOrdered <= 1) { - window.alert("Quantity can't be split"); + if (qtyDispatched >= qtyOrdered || qtyOrdered <= 1) { + window.alert("Remain quantity to dispatch is too low to be split"); } else if (qtyDispatched < qtyOrdered) { //replace tr suffix nbr $row.html($row.html().replace(/_0_/g,"_"+nbrTrs+"_")); diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index f28b51a7a97..13f2a280629 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -339,16 +339,17 @@ if (empty($reshook)) { } } + // Loop lines to calculate $totalqty for ($i = 1; $i <= $num; $i++) { - $idl = "idl".$i; + $idl = "idl".$i; // id line source - $sub_qty = array(); - $subtotalqty = 0; + //$sub_qty = array(); + //$subtotalqty = 0; - $j = 0; - $batch = "batchl".$i."_0"; - $stockLocation = "ent1".$i."_0"; - $qty = "qtyl".$i; + //$j = 0; + //$batch = "batchl".$i."_0"; + //$stockLocation = "ent1".$i."_0"; + $qty = "qtyl".$i; // qty //reception line for product with no batch management and no multiple stock location if (GETPOST($qty, 'alpha') > 0) { @@ -362,6 +363,7 @@ if (empty($reshook)) { if ($totalqty > 0) { // There is at least one thing to ship for ($i = 1; $i <= $num; $i++) { + $idl = "idl".$i; // id line source $lineToTest = ''; $lineId = GETPOST($idl, 'int'); foreach ($objectsrc->lines as $linesrc) { @@ -375,26 +377,28 @@ if (empty($reshook)) { } $qty = "qtyl".$i; $comment = "comment".$i; - // EATBY <-> DLUO see productbatch.class.php - // SELLBY <-> DLC + // EATBY <-> DLUO and SELLBY <-> DLC, see productbatch.class.php $eatby = "dluo".$i; $sellby = "dlc".$i; $batch = "batch".$i; $cost_price = "cost_price".$i; - //if (GETPOST($qty, 'int') > 0 || (GETPOST($qty, 'int') == 0 && getDolGlobalString('RECEPTION_GETS_ALL_ORDER_PRODUCTS')) || (GETPOST($qty, 'int') < 0 && getDolGlobalString('RECEPTION_ALLOW_NEGATIVE_QTY'))) { - if (GETPOST($qty, 'int') > 0 || (GETPOST($qty, 'int') == 0 && $conf->global->RECEPTION_GETS_ALL_ORDER_PRODUCTS)) { - $ent = "entl".$i; + //var_dump(GETPOST("productl".$i, 'int').' '.GETPOST('entl'.$i, 'int').' '.GETPOST($idl, 'int').' '.GETPOST($qty, 'int').' '.GETPOST($batch, 'alpha')); + //if (GETPOST($qty, 'int') > 0 || (GETPOST($qty, 'int') == 0 && getDolGlobalString('RECEPTION_GETS_ALL_ORDER_PRODUCTS')) || (GETPOST($qty, 'int') < 0 && getDolGlobalString('RECEPTION_ALLOW_NEGATIVE_QTY'))) { + if (GETPOST($qty, 'int') > 0 || (GETPOST($qty, 'int') == 0 && getDolGlobalString('RECEPTION_GETS_ALL_ORDER_PRODUCTS'))) { + $ent = "entl".$i; $idl = "idl".$i; $entrepot_id = is_numeric(GETPOST($ent, 'int')) ? GETPOST($ent, 'int') : GETPOST('entrepot_id', 'int'); + /* if (!empty($lineToTest)) { $fk_product = $lineToTest->fk_product; } else { $fk_product = $linesrc->fk_product; - } + }*/ + $fk_product = GETPOST("productl".$i, 'int'); if ($entrepot_id < 0) { $entrepot_id = ''; @@ -402,6 +406,7 @@ if (empty($reshook)) { if (!($fk_product > 0) && empty($conf->global->STOCK_SUPPORTS_SERVICES)) { $entrepot_id = 0; } + $eatby = GETPOST($eatby, 'alpha'); $sellby = GETPOST($sellby, 'alpha'); $eatbydate = str_replace('/', '-', $eatby); @@ -419,7 +424,6 @@ if (empty($reshook)) { } } - // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost(null, $object); if ($ret < 0) { @@ -941,7 +945,7 @@ if ($action == 'create') { print dol_get_fiche_end(); - // Reception lines + // Number of lines show on the reception card $numAsked = 0; /** @@ -954,7 +958,7 @@ if ($action == 'create') { foreach ($_POST as $key => $value) { // If create form is coming from the button "Create Reception" of previous page - // without batch module enabled + // without batch module enabled or product with no lot/serial $reg = array(); if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) { $numAsked++; @@ -969,10 +973,10 @@ if ($action == 'create') { $ent = "entrepot_" . $paramSuffix; $pu = "pu_" . $paramSuffix; // This is unit price including discount $fk_commandefourndet = "fk_commandefourndet_" . $paramSuffix; - $dispatchLines[$numAsked] = array('prod' => GETPOST($prod, 'int'), 'qty' => price2num(GETPOST($qty), 'MS'), 'ent' => GETPOST($ent, 'int'), 'pu' => price2num(GETPOST($pu), 'MU'), 'comment' => GETPOST('comment'), 'fk_commandefourndet' => GETPOST($fk_commandefourndet, 'int')); + $dispatchLines[$numAsked] = array('paramSuffix'=>$paramSuffix, 'prod' => GETPOST($prod, 'int'), 'qty' => price2num(GETPOST($qty), 'MS'), 'ent' => GETPOST($ent, 'int'), 'pu' => price2num(GETPOST($pu), 'MU'), 'comment' => GETPOST('comment'), 'fk_commandefourndet' => GETPOST($fk_commandefourndet, 'int')); } - // with batch module enabled + // with batch module enabled and product with lot/serial if (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) { $numAsked++; $paramSuffix = $reg[1] . '_' . $reg[2]; @@ -990,11 +994,11 @@ if ($action == 'create') { $dDLUO = dol_mktime(12, 0, 0, GETPOST('dluo_'.$paramSuffix.'month', 'int'), GETPOST('dluo_'.$paramSuffix.'day', 'int'), GETPOST('dluo_'.$paramSuffix.'year', 'int')); $dDLC = dol_mktime(12, 0, 0, GETPOST('dlc_'.$paramSuffix.'month', 'int'), GETPOST('dlc_'.$paramSuffix.'day', 'int'), GETPOST('dlc_'.$paramSuffix.'year', 'int')); $fk_commandefourndet = 'fk_commandefourndet_'.$paramSuffix; - $dispatchLines[$numAsked] = array('prod' => GETPOST($prod, 'int'), 'qty' => price2num(GETPOST($qty), 'MS'), 'ent' => GETPOST($ent, 'int'), 'pu' => price2num(GETPOST($pu), 'MU'), 'comment' => GETPOST('comment'), 'fk_commandefourndet' => GETPOST($fk_commandefourndet, 'int'), 'DLC'=> $dDLC, 'DLUO'=> $dDLUO, 'lot'=> GETPOST($lot, 'alpha')); + $dispatchLines[$numAsked] = array('paramSuffix'=>$paramSuffix, 'prod' => GETPOST($prod, 'int'), 'qty' => price2num(GETPOST($qty), 'MS'), 'ent' => GETPOST($ent, 'int'), 'pu' => price2num(GETPOST($pu), 'MU'), 'comment' => GETPOST('comment'), 'fk_commandefourndet' => GETPOST($fk_commandefourndet, 'int'), 'DLC'=> $dDLC, 'DLUO'=> $dDLUO, 'lot'=> GETPOST($lot, 'alpha')); } // If create form is coming from same page, it means that post was sent but an error occured - if (preg_match('/^productid([0-9]+)$/i', $key, $reg)) { + if (preg_match('/^productl([0-9]+)$/i', $key, $reg)) { $numAsked++; $paramSuffix = $reg[1]; $suffix2numAsked[$paramSuffix] = $numAsked; @@ -1116,9 +1120,13 @@ if ($action == 'create') { $product->fetch($line->fk_product); $product->load_stock('warehouseopen'); // Load all $product->stock_warehouse[idwarehouse]->detail_batch //var_dump($product->stock_warehouse[1]); + //var_dump($dispatchLines[$indiceAsked]); print '
'; } if (isModEnabled('stock')) { - print ''; + print ''; } if (isModEnabled('productbatch')) { From 165d958a6dc7babd7cdbf6bf8547477b49f9ffec Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 19:17:34 +0200 Subject: [PATCH 20/20] Fix trans --- htdocs/reception/document.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/reception/document.php b/htdocs/reception/document.php index dbb435b15dd..56854244f7b 100644 --- a/htdocs/reception/document.php +++ b/htdocs/reception/document.php @@ -41,7 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php'; // Load translation files required by the page -$langs->loadLangs(array('companies', 'other')); +$langs->loadLangs(array('receptions', 'companies', 'other')); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm');
'.$langs->trans("Description").''; -print nl2br($object->description); +print dol_htmlentitiesbr($object->description); print '
'.$langs->trans("Description").''; - print nl2br($object->description); + print dol_htmlentitiesbr($object->description); print '
'.$langs->trans("Description").''; - print nl2br($projectstatic->description); + print dol_htmlentitiesbr($projectstatic->description); print '
'; print ''; // ancre pour retourner sur la ligne + + print ''; + if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice print ''; @@ -1977,12 +1985,24 @@ if ($action == 'create') { if (isModEnabled('productbatch')) { if (isset($lines[$i]->batch)) { print ''; - print ''; - $detail = ''; - if ($lines[$i]->product->status_batch) { - $detail .= $langs->trans("Batch").': '.$lines[$i]->batch; - if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { - $detail .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($lines[$i]->sellby, "day"); + print ''; + $detail = $langs->trans("NA"); + if ($lines[$i]->product->status_batch > 0 && $lines[$i]->fk_product > 0) { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; + $productlot = new Productlot($db); + $reslot = $productlot->fetch(0, $lines[$i]->fk_product, $lines[$i]->batch); + if ($reslot > 0) { + $detail = $productlot->getNomUrl(1); + } else { + // lot is not created and info is only in reception lines + $batchinfo = $langs->trans("Batch").': '.$lines[$i]->batch; + if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + $batchinfo .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($lines[$i]->sellby, "day"); + } + if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { + $batchinfo .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($lines[$i]->eatby, "day"); + } + $detail = $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"), $batchinfo); } if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { $detail .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($lines[$i]->eatby, "day"); From 02d4b130b973e9e2e1b1ccdaa14d02f1e90e3cfb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Apr 2023 19:03:17 +0200 Subject: [PATCH 19/20] Fix label --- htdocs/reception/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index 13f2a280629..84a45822245 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -1723,7 +1723,7 @@ if ($action == 'create') { print $langs->trans("QtyReceived").' - '; } if (isModEnabled('stock')) { - print $langs->trans("WarehouseSource").' - '; + print $langs->trans("WarehouseTarget").' - '; } if (isModEnabled('productbatch')) { print $langs->trans("Batch"); @@ -1743,7 +1743,7 @@ if ($action == 'create') { print ''.$langs->trans("QtyReceived").''.$langs->trans("WarehouseSource").''.$langs->trans("WarehouseTarget").'