diff --git a/ChangeLog.md b/ChangeLog.md index 431b0a3..eea29a5 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -8,6 +8,7 @@ - Affichage du libellé "Zone" devant chaque sélecteur quotidien. - Ajout de la traduction "Meals" en "Repas". - Ajout du script de mise à jour SQL (`sql/update_all.sql`) pour créer les compteurs hebdomadaires sur les données existantes. +- Compatibilité Multisociété : partage des feuilles de temps et de la numérotation associée via hooks. - Redirection automatique vers la feuille existante en cas de création en doublon / Automatic redirect to the existing sheet when attempting a duplicate creation. - Ajout d'un accès rapide à la création de feuille d'heures via le menu supérieur. diff --git a/README.md b/README.md index 62db4c5..af12ddc 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ ## Features - Statut "Scellée" / "Sealed" pour verrouiller les feuilles approuvées. +- Compatibilité Multisociété pour partager les feuilles de temps et leur numérotation. - Redirection automatique vers la feuille existante en cas de doublon / Automatic redirect to the existing sheet when a duplicate is requested. Description of the module... diff --git a/class/actions_timesheetweek.class.php b/class/actions_timesheetweek.class.php index cb776ed..0f167e8 100644 --- a/class/actions_timesheetweek.class.php +++ b/class/actions_timesheetweek.class.php @@ -1,7 +1,18 @@ timesheetweek->enabled)) { + return 0; + } + + if (!function_exists('timesheetweek_build_multicompany_sharing_config')) { + dol_include_once('/timesheetweek/lib/timesheetweek.lib.php'); + } + + $sharing = timesheetweek_build_multicompany_sharing_config(); + if (empty($sharing)) { + return 0; + } + + if (empty($hookmanager->resArray) || !is_array($hookmanager->resArray)) { + // EN: Ensure the hook manager stores an array before merging definitions. + // FR: S'assurer que le gestionnaire de hooks conserve un tableau avant de fusionner les définitions. + $hookmanager->resArray = array(); + } + + // EN: Merge TimesheetWeek sharing options with existing ones. + // FR: Fusionner les options de partage TimesheetWeek avec les options existantes. + $hookmanager->resArray = array_merge($hookmanager->resArray, $sharing); + + return 1; * Inject TimesheetWeek entry into the quick add dropdown menu. * Injecter une entrée TimesheetWeek dans le menu déroulant de création rapide. * diff --git a/core/modules/modTimesheetWeek.class.php b/core/modules/modTimesheetWeek.class.php index 69a0dbe..9ca5746 100644 --- a/core/modules/modTimesheetWeek.class.php +++ b/core/modules/modTimesheetWeek.class.php @@ -94,7 +94,7 @@ public function __construct($db) $this->picto = 'bookcal'; // Define some features supported by module (triggers, login, substitutions, menus, css, etc...) - $this->module_parts = array( + $this->module_parts = array( // Set this to 1 if module has its own trigger directory (core/triggers) 'triggers' => 1, // Set this to 1 if module has its own login method file (core/login) @@ -123,14 +123,15 @@ public function __construct($db) ), // Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context to 'all' /* BEGIN MODULEBUILDER HOOKSCONTEXTS */ - // EN: Register the top right menu hook to inject quick creation entry. - // FR: Enregistrer le hook du menu supérieur droit pour injecter l'entrée de création rapide. - 'hooks' => array( - 'data' => array( - 'toprightmenu', - ), - 'entity' => '0', - ), + // EN: Register the top right menu hook to inject quick creation entry. + // FR: Enregistrer le hook du menu supérieur droit pour injecter l'entrée de création rapide. + 'hooks' => array( + 'data' => array( + 'toprightmenu', + 'multicompanysharing', + ), + 'entity' => '0', + ), /* END MODULEBUILDER HOOKSCONTEXTS */ // Set this to 1 if features of module are opened to external users 'moduleforexternal' => 0, @@ -601,13 +602,126 @@ public function __construct($db) ); $this->import_run_sql_after_array[$r] = array(); $r++; */ - /* END MODULEBUILDER IMPORT MYOBJECT */ - } - - /** - * Function called when module is enabled. - * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. - * It also creates data directories + /* END MODULEBUILDER IMPORT MYOBJECT */ + } + + /** + * EN: Build the Multicompany sharing configuration provided by this module. + * FR: Construire la configuration de partage Multisociété fournie par ce module. + * + * @return array + */ + private function getMulticompanySharingParameters() + { + if (!function_exists('timesheetweek_build_multicompany_sharing_config')) { + dol_include_once('/timesheetweek/lib/timesheetweek.lib.php'); + } + + // EN: Reuse the shared helper so definitions stay consistent across hooks. + // FR: Réutiliser l'aide partagée afin de garder des définitions cohérentes entre les hooks. + return timesheetweek_build_multicompany_sharing_config(); + } + + /** + * EN: Register the sharing configuration inside the Multicompany constant. + * FR: Enregistrer la configuration de partage dans la constante Multisociété. + * + * @return int + */ + private function registerMulticompanySharingOptions() + { + global $conf; + + // EN: Skip registration when the Multicompany module is disabled. + // FR: Ignorer l'enregistrement lorsque le module Multisociété est désactivé. + if (empty($conf->multicompany->enabled) && !isModEnabled('multicompany')) { + return 1; + } + + $params = $this->getMulticompanySharingParameters(); + if (empty($params)) { + return 1; + } + + $current = array(); + if (!empty($conf->global->MULTICOMPANY_EXTERNAL_MODULES_SHARING)) { + $decoded = json_decode($conf->global->MULTICOMPANY_EXTERNAL_MODULES_SHARING, true); + if (is_array($decoded)) { + $current = $decoded; + } + } + + $current = array_merge($current, $params); + + $jsonformat = json_encode($current); + if ($jsonformat === false) { + dol_syslog(__METHOD__.': failed to encode sharing parameters to JSON', LOG_ERR); + return 0; + } + + $res = dolibarr_set_const($this->db, 'MULTICOMPANY_EXTERNAL_MODULES_SHARING', $jsonformat, 'chaine', 0, '', 0); + if ($res > 0) { + // EN: Keep the in-memory configuration synchronised with the stored value. + // FR: Garder la configuration en mémoire synchronisée avec la valeur stockée. + $conf->global->MULTICOMPANY_EXTERNAL_MODULES_SHARING = $jsonformat; + } + + return $res; + } + + /** + * EN: Remove the sharing configuration from the Multicompany constant. + * FR: Retirer la configuration de partage de la constante Multisociété. + * + * @return int + */ + private function unregisterMulticompanySharingOptions() + { + global $conf; + + // EN: No action required if Multicompany is absent. + // FR: Aucune action nécessaire si Multisociété est absent. + if (empty($conf->multicompany->enabled) && !isModEnabled('multicompany')) { + return 1; + } + + if (empty($conf->global->MULTICOMPANY_EXTERNAL_MODULES_SHARING)) { + return 1; + } + + $decoded = json_decode($conf->global->MULTICOMPANY_EXTERNAL_MODULES_SHARING, true); + if (!is_array($decoded) || empty($decoded['timesheetweek'])) { + return 1; + } + + unset($decoded['timesheetweek']); + + if (empty($decoded)) { + // EN: Preserve an object structure when no external sharings remain. + // FR: Préserver une structure objet lorsqu'aucun partage externe ne reste. + $decoded = new stdClass(); + } + + $jsonformat = json_encode($decoded); + if ($jsonformat === false) { + dol_syslog(__METHOD__.': failed to encode sharing parameters to JSON', LOG_ERR); + return 0; + } + + $res = dolibarr_set_const($this->db, 'MULTICOMPANY_EXTERNAL_MODULES_SHARING', $jsonformat, 'chaine', 0, '', 0); + if ($res > 0) { + // EN: Synchronise the in-memory configuration with the stored JSON string. + // FR: Synchroniser la configuration en mémoire avec la chaîne JSON enregistrée. + $conf->global->MULTICOMPANY_EXTERNAL_MODULES_SHARING = $jsonformat; + } + + return $res; + } + + /** + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories * * @param string $options Options when enabling module ('', 'noboxes') * @return int<-1,1> 1 if OK, <=0 if KO @@ -669,7 +783,12 @@ public function init($options = '') } } - return $this->_init($sql, $options); + $result = $this->_init($sql, $options); + if ($result > 0) { + $this->registerMulticompanySharingOptions(); + } + + return $result; } /** @@ -682,7 +801,12 @@ public function init($options = '') */ public function remove($options = '') { - $sql = array(); - return $this->_remove($sql, $options); - } + $sql = array(); + $result = $this->_remove($sql, $options); + if ($result > 0) { + $this->unregisterMulticompanySharingOptions(); + } + + return $result; + } } diff --git a/langs/en_US/timesheetweek.lang b/langs/en_US/timesheetweek.lang index ddd8670..9e4c2a7 100644 --- a/langs/en_US/timesheetweek.lang +++ b/langs/en_US/timesheetweek.lang @@ -15,6 +15,10 @@ ModuleTimesheetWeekDesc = TimesheetWeek description TimesheetWeekSetup = TimesheetWeek setup Settings = Settings TimesheetWeekSetupPage = TimesheetWeek setup page +TimesheetWeekSharingTimesheet = Timesheet sharing +TimesheetWeekSharingTimesheetTooltip = Allow sharing weekly timesheets between companies. +TimesheetWeekSharingNumbering = Timesheet numbering sharing +TimesheetWeekSharingNumberingTooltip = Share the weekly timesheet numbering sequence between companies. NewSection=New section TIMESHEETWEEK_MYPARAM1 = My param 1 TIMESHEETWEEK_MYPARAM1Tooltip = My param 1 tooltip diff --git a/langs/fr_FR/timesheetweek.lang b/langs/fr_FR/timesheetweek.lang index 8b38dda..2a9ac04 100644 --- a/langs/fr_FR/timesheetweek.lang +++ b/langs/fr_FR/timesheetweek.lang @@ -15,6 +15,10 @@ ModuleTimesheetWeekDesc = Description du module TimesheetWeek TimesheetWeekSetup = Paramétrage TimesheetWeek Settings = Paramètres TimesheetWeekSetupPage = Page de configuration TimesheetWeek +TimesheetWeekSharingTimesheet = Partage des feuilles de temps +TimesheetWeekSharingTimesheetTooltip = Autoriser le partage des feuilles hebdomadaires entre sociétés. +TimesheetWeekSharingNumbering = Partage de la numérotation des feuilles de temps +TimesheetWeekSharingNumberingTooltip = Partager la séquence de numérotation des feuilles hebdomadaires entre sociétés. NewSection=Nouvelle section TIMESHEETWEEK_MYPARAM1 = Mon paramètre 1 TIMESHEETWEEK_MYPARAM1Tooltip = Info-bulle de mon paramètre 1 diff --git a/lib/timesheetweek.lib.php b/lib/timesheetweek.lib.php index 886e38d..b231b5d 100644 --- a/lib/timesheetweek.lib.php +++ b/lib/timesheetweek.lib.php @@ -21,6 +21,72 @@ * \brief Library files with common functions for TimesheetWeek */ +/** + * EN: Provide the Multicompany sharing configuration for TimesheetWeek. + * FR: Fournir la configuration de partage Multisociété pour TimesheetWeek. + * + * @return array + */ +function timesheetweek_build_multicompany_sharing_config() +{ + global $conf; + + // EN: Stop when the module is disabled to avoid polluting the Multicompany setup. + // FR: Arrêter lorsque le module est désactivé pour éviter de polluer la configuration Multisociété. + if (empty($conf->timesheetweek->enabled)) { + return array(); + } + + return array( + 'timesheetweek' => array( + 'sharingelements' => array( + 'timesheetweek' => array( + 'type' => 'object', + 'icon' => 'calendar-check-o', + 'lang' => 'timesheetweek@timesheetweek', + 'transkey' => 'TimesheetWeekSharingTimesheet', + 'tooltip' => 'TimesheetWeekSharingTimesheetTooltip', + 'enable' => '! empty($conf->timesheetweek->enabled)', + 'display' => '! empty($conf->global->MULTICOMPANY_SHARINGS_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true, + ), + ), + ), + 'timesheetweek_numbering' => array( + 'type' => 'object', + 'icon' => 'hashtag', + 'lang' => 'timesheetweek@timesheetweek', + 'transkey' => 'TimesheetWeekSharingNumbering', + 'tooltip' => 'TimesheetWeekSharingNumberingTooltip', + 'mandatory' => 'timesheetweek', + 'enable' => '! empty($conf->timesheetweek->enabled)', + 'display' => '! empty($conf->global->MULTICOMPANY_TIMESHEETWEEK_SHARING_ENABLED)', + 'input' => array( + 'global' => array( + 'hide' => true, + 'del' => true, + ), + 'timesheetweek' => array( + 'showhide' => true, + 'del' => true, + ), + ), + ), + ), + 'sharingmodulename' => array( + 'timesheetweek' => 'timesheetweek', + 'timesheetweek_numbering' => 'timesheetweek', + ), + 'addzero' => array( + 'timesheetweek', + ), + ), + ); +} + /** * Prepare admin pages header *