Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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...
Expand Down
54 changes: 52 additions & 2 deletions class/actions_timesheetweek.class.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
<?php
/*
* EN: Actions class to expose TimesheetWeek hooks.
* FR: Classe d'actions pour exposer les hooks de TimesheetWeek.
*/

// EN: Protect direct access.
// FR: Protéger contre les accès directs.
if (!defined('DOL_DOCUMENT_ROOT')) {
die('Dolibarr environment not found');
}

/**
* Hook class for TimesheetWeek module.
* Classe de hook pour le module TimesheetWeek.
* EN: Hook class for TimesheetWeek.
* FR: Classe de hook pour TimesheetWeek.
*/
class ActionsTimesheetweek
{
Expand Down Expand Up @@ -39,6 +50,45 @@ public function __construct($db)
}

/**
* EN: Provide Multicompany sharing options via hook.
* FR: Fournir les options de partage Multisociété via le hook.
*
* @param array $parameters Hook parameters
* @param CommonObject|null $object Related object
* @param string $action Current action string
* @param HookManager $hookmanager Hook manager instance
* @return int
*/
public function multicompanysharing($parameters, &$object, &$action, $hookmanager)
{
global $conf;

// EN: Abort when the module is disabled to avoid useless processing.
// FR: Abandonner lorsque le module est désactivé pour éviter un traitement inutile.
if (empty($conf->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.
*
Expand Down
164 changes: 144 additions & 20 deletions core/modules/modTimesheetWeek.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

/**
Expand All @@ -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;
}
}
4 changes: 4 additions & 0 deletions langs/en_US/timesheetweek.lang
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions langs/fr_FR/timesheetweek.lang
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
66 changes: 66 additions & 0 deletions lib/timesheetweek.lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down