From 28d01777631fe37ea13c7ee42855be75e099c53a Mon Sep 17 00:00:00 2001 From: Sylvain Legrand Date: Thu, 7 Nov 2024 21:37:08 +0300 Subject: [PATCH] add option relatives to projects New option to attach files from the linked project on standards elements (proposal, order, invoices, ...) Add files from elements linked to the project when we send mail from this project. --- admin/attachments_setup.php | 1 + class/actions_attachments.class.php | 95 ++++++++++++++++++++++++++++- langs/en_US/attachments.lang | 2 + langs/fr_FR/attachments.lang | 2 + 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/admin/attachments_setup.php b/admin/attachments_setup.php index 7a1130f..43f91bb 100644 --- a/admin/attachments_setup.php +++ b/admin/attachments_setup.php @@ -113,6 +113,7 @@ // Example with a yes / no select setup_print_on_off('ATTACHMENTS_INCLUDE_PRODUCT_LINES'); setup_print_on_off('ATTACHMENTS_INCLUDE_OBJECT_LINKED'); +setup_print_on_off('ATTACHMENTS_INCLUDE_PROJECT_LINKED'); if (isModEnabled('ecm')) { diff --git a/class/actions_attachments.class.php b/class/actions_attachments.class.php index acb6f2a..7c7e559 100644 --- a/class/actions_attachments.class.php +++ b/class/actions_attachments.class.php @@ -27,6 +27,8 @@ * Class ActionsAttachments */ require_once __DIR__.'/../backport/v19/core/class/commonhookactions.class.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; class ActionsAttachments extends \attachments\RetroCompatCommonHookActions { /** @@ -55,7 +57,8 @@ class ActionsAttachments extends \attachments\RetroCompatCommonHookActions , 'AttachmentsTitleFactureFournisseur' => 35 , 'AttachmentsTitleFicheInter' => 40 , 'AttachmentsSociete' => 50 - , 'AttachmentsTitleTask' =>60 + , 'AttachmentsTitleProject' => 55 + , 'AttachmentsTitleTask' => 60 , 'AttachmentsTitleEcm' => 500 ); @@ -71,6 +74,7 @@ class ActionsAttachments extends \attachments\RetroCompatCommonHookActions , 'fichinter' => 'AttachmentsTitleFicheInter' , 'societe' => 'AttachmentsSociete' , 'ecm' => 'AttachmentsTitleEcm' + , 'project' => 'AttachmentsTitleProject' , 'project_task' => 'AttachmentsTitleTask' , 'shipping' => 'AttachmentsShipping' ); @@ -127,10 +131,20 @@ function doActions($parameters, &$object, &$action, $hookmanager) $this->current_object = $object; if (getDolGlobalString('ATTACHMENTS_INCLUDE_OBJECT_LINKED')) { + if (getDolGlobalString('ATTACHMENTS_INCLUDE_PROJECT_LINKED') && !empty($this->current_object->fk_project)) { + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'element_element (fk_source, sourcetype, fk_target, targettype) VALUES ('.$this->current_object->id.', "'.$this->current_object->element.'", '.$this->current_object->fk_project.', "project")'; + $resql = $this->db->query($sql); + $this->db->free($resql); + } $this->current_object->fetchObjectLinked(); if(!empty($this->current_object->fk_soc)) $fk_soc = $this->current_object->fk_soc ?? 0; else $fk_soc = $this->current_object->socid ?? 0; $this->current_object->linkedObjects['societe'][$fk_soc] = $this->current_object->thirdparty; + if (getDolGlobalString('ATTACHMENTS_INCLUDE_PROJECT_LINKED') && !empty($this->current_object->fk_project)) { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'element_element WHERE fk_source = '.$this->current_object->id.' AND sourcetype LIKE "'.$this->current_object->element.'" AND fk_target = '.$this->current_object->fk_project.' AND targettype LIKE "project"'; + $resql = $this->db->query($sql); + $this->db->free($resql); + } } if (empty($this->current_object->linkedObjects[$this->current_object->element])) $this->current_object->linkedObjects[$this->current_object->element] = array(); @@ -181,6 +195,84 @@ function doActions($parameters, &$object, &$action, $hookmanager) } } } + // Propal linked to the project + $staticPropal = new Propal($this->db); + $listPropals = $this->current_object->get_element_list('propal', 'propal', 'datep', '', '', 'fk_projet'); + if (is_array($listPropals) && count($listPropals) > 0) { + $baseDirPropal = !empty($conf->propal->multidir_output[$conf->entity]) ? $conf->propal->multidir_output[$conf->entity] : $conf->propal->dir_output; + $num = count($listPropals); + for ($p = 0; $p < $num; $p++) { + $tmp = explode('_', $listPropals[$p]); + $idofpropal = $tmp[0]; + $staticPropal->fetch($idofpropal); + $propalRef = dol_sanitizeFileName($staticPropal->ref); + $dirPropal = $baseDirPropal.'/'.$propalRef; + $file_list = dol_dir_list($dirPropal, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + if (!empty($file_list)) { + $key = $this->TTileKeyByElement['propal']; + foreach ($file_list as $file_info) { + $fullname_md5 = md5($file_info['fullname']); + $this->TFilePathByTitleKey[$key][$propalRef][$fullname_md5] = array('name' => $file_info['name'], + 'path' => $file_info['path'], + 'fullname' => $file_info['fullname'], + 'fullname_md5' => $fullname_md5 + ); + } + } + } + } + // Order linked to the project + $staticOrder = new Commande($this->db); + $listOrders = $this->current_object->get_element_list('commande', 'commande', 'date_commande', '', '', 'fk_projet'); + if (is_array($listOrders) && count($listOrders) > 0) { + $baseDirOrder = !empty($conf->commande->multidir_output[$conf->entity]) ? $conf->commande->multidir_output[$conf->entity] : $conf->commande->dir_output; + $num = count($listOrders); + for ($p = 0; $p < $num; $p++) { + $tmp = explode('_', $listOrders[$p]); + $idoforder = $tmp[0]; + $staticOrder->fetch($idoforder); + $orderRef = dol_sanitizeFileName($staticOrder->ref); + $dirOrder = $baseDirOrder.'/'.$orderRef; + $file_list = dol_dir_list($dirOrder, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + if (!empty($file_list)) { + $key = $this->TTileKeyByElement['commande']; + foreach ($file_list as $file_info) { + $fullname_md5 = md5($file_info['fullname']); + $this->TFilePathByTitleKey[$key][$orderRef][$fullname_md5] = array('name' => $file_info['name'], + 'path' => $file_info['path'], + 'fullname' => $file_info['fullname'], + 'fullname_md5' => $fullname_md5 + ); + } + } + } + } + // Invoice linked to the project + $staticInvoice = new Facture($this->db); + $listInvoices = $this->current_object->get_element_list('facture', 'facture', 'datef', '', '', 'fk_projet'); + if (is_array($listInvoices) && count($listInvoices) > 0) { + $baseDirInvoice = !empty($conf->facture->multidir_output[$conf->entity]) ? $conf->facture->multidir_output[$conf->entity] : $conf->facture->dir_output; + $num = count($listInvoices); + for ($p = 0; $p < $num; $p++) { + $tmp = explode('_', $listInvoices[$p]); + $idofInvoice = $tmp[0]; + $staticInvoice->fetch($idofInvoice); + $InvoiceRef = dol_sanitizeFileName($staticInvoice->ref); + $dirInvoice = $baseDirInvoice.'/'.$InvoiceRef; + $file_list = dol_dir_list($dirInvoice, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + if (!empty($file_list)) { + $key = $this->TTileKeyByElement['facture']; + foreach ($file_list as $file_info) { + $fullname_md5 = md5($file_info['fullname']); + $this->TFilePathByTitleKey[$key][$InvoiceRef][$fullname_md5] = array('name' => $file_info['name'], + 'path' => $file_info['path'], + 'fullname' => $file_info['fullname'], + 'fullname_md5' => $fullname_md5 + ); + } + } + } + } } // Gestion des objets standards foreach ($this->current_object->linkedObjects as $element => $TLinkedObject) @@ -195,6 +287,7 @@ function doActions($parameters, &$object, &$action, $hookmanager) $sub_element_to_use = ''; $subdir = ''; if ($element === 'fichinter') $element_to_use = 'ficheinter'; + elseif ($element === 'project') $element_to_use = 'projet'; elseif ($element === 'order_supplier') { $element_to_use = 'fournisseur'; $subdir = '/commande'; } elseif ($element === 'invoice_supplier') { $element_to_use = 'fournisseur'; $sub_element_to_use = 'facture'; /* $subdir is defined in the next loop */ } elseif ($element === 'shipping') {$element_to_use = 'expedition'; $subdir = '/sending';} diff --git a/langs/en_US/attachments.lang b/langs/en_US/attachments.lang index 2075216..a301fc5 100644 --- a/langs/en_US/attachments.lang +++ b/langs/en_US/attachments.lang @@ -12,6 +12,7 @@ AbricotNeedUpdate = The 'Abricot' module need to be update # SETUP ATTACHMENTS_INCLUDE_PRODUCT_LINES = Search files related to products /services of the current document ATTACHMENTS_INCLUDE_OBJECT_LINKED = Search files related to the linked objects of the current document +ATTACHMENTS_INCLUDE_PROJECT_LINKED = Search files related to the linked project of the current document (requires activation of previous option) ATTACHMENTS_ECM_SCANDIR = Search files in the following folder # FORMCONFIRM @@ -29,6 +30,7 @@ AttachmentsTitleFicheInter = Intervention AttachmentsSociete = Company AttachmentsTitleEcm = Documents (EDM) AttachmentsShipping = Shipping +AttachmentsTitleProject = Project AttachmentsTitleTask = Task AttachmentsFiltered = Elements corresponding to your search term diff --git a/langs/fr_FR/attachments.lang b/langs/fr_FR/attachments.lang index dc7ca44..6ab6d26 100644 --- a/langs/fr_FR/attachments.lang +++ b/langs/fr_FR/attachments.lang @@ -11,6 +11,7 @@ AbricotNeedUpdate=Le module abricot doit être mis à jour # SETUP ATTACHMENTS_INCLUDE_PRODUCT_LINES=Activer la recherche dans les fichiers provenant des produits/services du document courant ATTACHMENTS_INCLUDE_OBJECT_LINKED=Activer la recherche dans les fichiers provenant des éléments liés au document courant +ATTACHMENTS_INCLUDE_PROJECT_LINKED=Activer la recherche dans les fichiers provenant du projet lié au document courant (nécessite l'activation de l'option précédente) ATTACHMENTS_ECM_SCANDIR=Activer la recherche dans le répertoire suivant # FORMCONFIRM @@ -27,6 +28,7 @@ AttachmentsTitleFactureFournisseur=Facture fournisseur AttachmentsTitleFicheInter=Intervention AttachmentsSociete=Société AttachmentsTitleEcm=Documents (GED) +AttachmentsTitleProject=Projet AttachmentsTitleTask=Tâches AttachmentsShipping=Expedition