diff --git a/README.md b/README.md index 756f7a4..40233eb 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## Informations - Numéro du module : 436304 -- Dernière mise à jour : 19/01/2024 +- Dernière mise à jour : 07/03/2024 - Éditeur : [Evarisk](https://evarisk.com) - Thème : Eldy Menu - Licence : GPLv3 @@ -13,8 +13,8 @@ - Version : 1.3.0 - PHP : 7.4.33 -- Compatibilité : Dolibarr 16.0.0 - 18.0.4 -- Saturne framework : 1.2.1 +- Compatibilité : Dolibarr 16.0.0 - 18.0.5 +- Saturne framework : 1.3.0 ## Liens diff --git a/admin/setup.php b/admin/setup.php index 919ae5d..5ac7ac1 100644 --- a/admin/setup.php +++ b/admin/setup.php @@ -201,7 +201,7 @@ print ''; $confName = 'DOLIMEET_' . dol_strtoupper($satisfactionSurvey) . '_SATISFACTION_SURVEY_SHEET'; - print img_picto($langs->trans('Sheet'), $sheet->picto, 'class="pictofixedwidth"') . $sheet->selectSheetList($conf->global->$confName, $satisfactionSurvey . '_satisfaction_survey_model', '', '1', 0, 0, [], '', 0, 0, 'minwidth400 maxwidth500'); + print img_picto($langs->trans('Sheet'), $sheet->picto, 'class="pictofixedwidth"') . $sheet->selectSheetList($conf->global->$confName, $satisfactionSurvey . '_satisfaction_survey_model', 's.type = "survey" AND s.status = ' . Sheet::STATUS_LOCKED, '1', 0, 0, [], '', 0, 0, 'minwidth400 maxwidth500'); print ''; } diff --git a/class/actions_dolimeet.class.php b/class/actions_dolimeet.class.php index 3bac708..ec6a0bf 100644 --- a/class/actions_dolimeet.class.php +++ b/class/actions_dolimeet.class.php @@ -247,7 +247,7 @@ public function printCommonFooter(array $parameters): int } else { $outputLine[$contact['rowid']] = ''; $outputLine[$contact['rowid']] .= ''; - $outputLine[$contact['rowid']] .= $form->textwithpicto($langs->trans('ClickHere'), $langs->trans('NeedToSetSatisfactionSurvey', $contact['code']), 1, 'warning') . ''; + $outputLine[$contact['rowid']] .= $form->textwithpicto($langs->trans('ClickHere'), $langs->trans('NeedToSetSatisfactionSurvey', dol_strtolower($langs->trans(ucfirst(dol_strtolower($contact['code']))))), 1, 'warning') . ''; $outputLine[$contact['rowid']] .= ''; } } @@ -432,14 +432,29 @@ function fillTable(data) { $filter = 't.status >= 0 AND t.type = "trainingsession" AND t.fk_contrat = ' . $object->id; $sessions = $session->fetchAll('', '', 0, 0, ['customsql' => $filter]); if (is_array($sessions) && !empty($sessions)) { - foreach ($sessions as $session) { - $sessionDurations += $session->duration; + foreach ($sessions as $sessionSingle) { + $sessionDurations += $sessionSingle->duration; + } + } + if (GETPOST('action') == 'edit_extras' && GETPOST('attribute') == 'trainingsession_durations') { + $out = ''; + $out .= '
'; + $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; + $out .= $form->select_duration('duration', $object->array_options['options_trainingsession_durations'], 0, 'text', 0, 1); + $out .= '' . ''; + } else { + $out = '' . ($object->array_options['options_trainingsession_durations'] > 0 ? convertSecondToTime($object->array_options['options_trainingsession_durations'], 'allhourmin') : '00:00') . ' - '; + $out .= $langs->trans('CalculatedTotalSessionDuration') . ' ' . ($sessionDurations > 0 ? convertSecondToTime($sessionDurations, 'allhourmin') : '00:00'); + if ($sessionDurations != $object->array_options['options_trainingsession_durations']) { + $out .= $form->textwithpicto('', $langs->trans('TrainingSessionDurationErrorMatching', $session->ref), 1, 'warning'); } - $out = '' . $langs->transnoentities('TrainingSessionDurations') . ''; - $out .= '' . ($sessionDurations > 0 ? convertSecondToTime($sessionDurations, 'allhourmin') : '00:00') . ''; + $out .= ''; } ?> array_options['options_trainingsession_durations'] = $duration; + $object->updateExtrafield('trainingsession_durations'); + return 1; + } } return 0; // or return 1 to replace standard code. } + /** + * Overloading the formObjectOptions function : replacing the parent's function with the one below + * + * @param array $parameters Hook metadatas (context, etc...) + * @param CommonObject $object Current object + * @param string $action Current action + * @return int 0 < on error, 0 on success, 1 to replace standard code + */ + public function formObjectOptions(array $parameters, $object, string $action): int + { + global $extrafields, $langs; + + if (strpos($parameters['context'], 'contractcard') !== false) { + $pictoPath = dol_buildpath('/custom/dolimeet/img/dolimeet_color.png', 1); + $picto = img_picto('', $pictoPath, '', 1, 0, 0, '', 'pictoModule'); + foreach ($extrafields->attributes['contrat']['enabled'] as $key => $moduleExtraFiels) { + if (strpos($moduleExtraFiels, 'dolimeet') !== false) { + $extrafields->attributes['contrat']['label'][$key] = $picto . $langs->transnoentities($extrafields->attributes['contrat']['label'][$key]); + } + } + } + + return 0; // or return 1 to replace standard code + } + + /** + * Overloading the printFieldListTitle function : replacing the parent's function with the one below + * + * @param array $parameters Hook metadatas (context, etc...) + * @param CommonObject $object Current object + * @param string $action Current action + * @return int 0 < on error, 0 on success, 1 to replace standard code + */ + public function printFieldPreListTitle(array $parameters, $object, string $action): int + { + global $extrafields, $langs; + + if (strpos($parameters['context'], 'contractlist') !== false) { + $pictoPath = dol_buildpath('/custom/dolimeet/img/dolimeet_color.png', 1); + $picto = img_picto('', $pictoPath, '', 1, 0, 0, '', 'pictoModule'); + foreach ($extrafields->attributes['contrat']['enabled'] as $key => $moduleExtraFiels) { + if (strpos($moduleExtraFiels, 'dolimeet') !== false) { + $extrafields->attributes['contrat']['label'][$key] = $picto . $langs->transnoentities($extrafields->attributes['contrat']['label'][$key]); + } + } + } + + return 0; // or return 1 to replace standard code + } + /** * Overloading the extendSheetLinkableObjectsList function : replacing the parent's function with the one below. * @@ -584,20 +659,23 @@ public function doActions(array $parameters, $object, string $action): int public function extendSheetLinkableObjectsList(array $linkableObjectTypes): int { require_once __DIR__ . '/../class/trainingsession.class.php'; + require_once __DIR__ . '/../lib/dolimeet_trainingsession.lib.php'; $trainingSession = new Trainingsession($this->db); $linkableObjectTypes['dolimeet_trainsess'] = [ - 'langs' => 'Trainingsession', - 'langfile' => 'dolimeet@dolimeet', - 'picto' => $trainingSession->picto, - 'className' => 'Trainingsession', - 'post_name' => 'fk_trainingsession', - 'link_name' => 'dolimeet_trainsess', - 'name_field' => 'ref', - 'create_url' => 'custom/dolimeet/view/trainingsession/session_card.php?action=create&object_type=trainingsession', - 'class_path' => 'custom/dolimeet/class/trainingsession.class.php', - 'lib_path' => 'custom/dolimeet/lib/dolimeet_trainingsession.lib.php', + 'langs' => 'Trainingsession', + 'langfile' => 'dolimeet@dolimeet', + 'picto' => $trainingSession->picto, + 'className' => 'Trainingsession', + 'name_field' => 'ref', + 'post_name' => 'fk_trainingsession', + 'link_name' => 'dolimeet_trainsess', + 'tab_type' => 'trainingsession', + 'hook_name_list' => 'trainingsessionlist', + 'hook_name_card' => 'trainingsessioncard', + 'create_url' => 'custom/dolimeet/view/trainingsession/session_card.php?action=create&object_type=trainingsession', + 'class_path' => 'custom/dolimeet/class/trainingsession.class.php' ]; $this->results = $linkableObjectTypes; @@ -845,11 +923,40 @@ public function saturneBuildDoc(array $parameters, CommonObject $object, string $document = new CompletioncertificateDocument($this->db); $signatory = new SaturneSignature($this->db, 'dolimeet', $object->element); - $duration = 0; - $sessions = $session->fetchAll('', '', 0, 0, ['customsql' => 't.fk_contrat = ' . $object->id . ' AND t.status >= 0']); + $contactList = []; + $signedTrainee = []; + $sessions = $session->fetchAll('', '', 0, 0, ['customsql' => 't.fk_contrat = ' . $object->id . ' AND t.status >= 0']); + // We retrieve internal & external user linked to the contract + foreach (['internal', 'external'] as $source) { + $contactList[$source] = $object->liste_contact(-1, $source, 0, 'TRAINEE'); + // We need our array keys to start with 1 for further logic + array_unshift($contactList[$source],''); + unset($contactList[$source][0]); + } + // Because of the structure of $contactList we need a second array where we will remove someone if he is present for ONE session + $absentTrainee = $contactList; + if (is_array($sessions) && !empty($sessions)) { foreach ($sessions as $session) { - $duration += $session->duration; + $signatories = $signatory->fetchSignatories($session->id, 'trainingsession', 'role = "Trainee"'); + foreach ($signatories as $signatory) { + $type = ($signatory->element_type == 'user' ? 'internal' : 'external'); + $absentId = array_column($absentTrainee[$type], 'id'); + + // We search for the key in $contactList corresponding to the current $signatory->element_id + array_unshift($absentId,''); + unset($absentId[0]); + // array_search return false (0) if it doesn't find, that's why we need our $absentTrainee array to start by 1 + $key = array_search($signatory->element_id, $absentId); + + if ($signatory->attendance != SaturneSignature::ATTENDANCE_ABSENT) { + // If the $signatory is present then we will remove it from the $absentTrainee array + if ($key > 0) { + unset($absentTrainee[$type][$key]); + } + $signedTrainee[$type][$signatory->element_id] += $session->duration; + } + } } $lastSession = end($sessions); $dateEnd = $lastSession->date_end; @@ -858,30 +965,37 @@ public function saturneBuildDoc(array $parameters, CommonObject $object, string } } - $contactList = []; - foreach (['internal', 'external'] as $source) { - $contactList = array_merge($contactList, $object->liste_contact(-1, $source, 0, 'TRAINEE')); + if (!empty($absentTrainee)) { + foreach ($absentTrainee as $absentType) { + foreach($absentType as $contact) { + setEventMessages($langs->trans('NoCertificateBecauseAbsent', $contact['lastname'], $contact['firstname']), [], 'warnings'); + } + } } $parameters['moreparams']['object'] = $object; $parameters['moreparams']['object']->element = 'trainingsession'; $parameters['moreparams']['object']->date_start = $object->array_options['options_trainingsession_start']; $parameters['moreparams']['object']->date_end = $object->array_options['options_trainingsession_end']; - $parameters['moreparams']['object']->duration = $duration; $parameters['moreparams']['object']->fk_contrat = $object->id; - if (!empty($contactList)) { - foreach ($contactList as $contact) { - $parameters['moreparams']['attendant'] = $signatory; - $parameters['moreparams']['attendant']->firstname = $contact['firstname']; - $parameters['moreparams']['attendant']->lastname = $contact['lastname']; - $parameters['moreparams']['attendant']->element_type = ($contact['source'] == 'external' ? 'socpeople' : 'user'); - $parameters['moreparams']['attendant']->element_id = $contact['id']; - - $document->element = 'trainingsessiondocument'; - $result = $document->generateDocument((!empty($parameters['models']) ? $parameters['models'][1] : $parameters['model']), $parameters['outputlangs'], $parameters['hidedetails'], $parameters['hidedesc'], $parameters['hideref'], $parameters['moreparams']); - if ($result <= 0) { - setEventMessages($document->error, $document->errors, 'errors'); + if (!empty($contactList) && !empty($signedTrainee)) { + foreach ($contactList as $contactType) { + foreach($contactType as $contact) { + if (is_array($signedTrainee[$contact['source']]) && array_key_exists($contact['id'], $signedTrainee[$contact['source']])) { + $parameters['moreparams']['attendant'] = $signatory; + $parameters['moreparams']['attendant']->firstname = $contact['firstname']; + $parameters['moreparams']['attendant']->lastname = $contact['lastname']; + $parameters['moreparams']['attendant']->element_type = ($contact['source'] == 'external' ? 'socpeople' : 'user'); + $parameters['moreparams']['attendant']->element_id = $contact['id']; + $parameters['moreparams']['object']->duration = $signedTrainee[$contact['source']][$contact['id']]; + + $document->element = 'trainingsessiondocument'; + $result = $document->generateDocument((!empty($parameters['models']) ? $parameters['models'][1] : $parameters['model']), $parameters['outputlangs'], $parameters['hidedetails'], $parameters['hidedesc'], $parameters['hideref'], $parameters['moreparams']); + if ($result <= 0) { + setEventMessages($document->error, $document->errors, 'errors'); + } + } } } diff --git a/core/modules/dolimeet/dolimeetdocuments/trainingsessiondocument/modules_trainingsessiondocument.php b/core/modules/dolimeet/dolimeetdocuments/trainingsessiondocument/modules_trainingsessiondocument.php deleted file mode 100644 index 1e981b0..0000000 --- a/core/modules/dolimeet/dolimeetdocuments/trainingsessiondocument/modules_trainingsessiondocument.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * or see https://www.gnu.org/ - */ - -/** - * \file core/modules/dolimeet/dolimeetdocuments/trainingsessiondocument/modules_trainingsessiondocument.php - * \ingroup dolimeet - * \brief File that contains parent class for trainingsession document models. - */ - -// Load Saturne libraries. -require_once __DIR__ . '/../../../../../../saturne/core/modules/saturne/modules_saturne.php'; - -/** - * Parent class for trainingsession document models. - */ -abstract class ModeleODTTrainingSessionDocument extends SaturneDocumentModel -{ - /** - * Return list of active generation modules. - * - * @param DoliDB $db Database handler. - * @param string $type Document type. - * @param int $maxfilenamelength Max length of value to show. - * @return array|int 0 if no module is activated, or array(key=>label). For modules that need directory scan, key is completed with ":filename". - * @throws Exception - */ - public static function liste_modeles(DoliDB $db, string $type, int $maxfilenamelength = 0): array - { - return parent::liste_modeles($db, 'trainingsessiondocument', $maxfilenamelength); - } -} diff --git a/core/modules/modDoliMeet.class.php b/core/modules/modDoliMeet.class.php index 745a348..2527256 100644 --- a/core/modules/modDoliMeet.class.php +++ b/core/modules/modDoliMeet.class.php @@ -78,7 +78,7 @@ public function __construct($db) $this->editor_url = 'https://evarisk.com'; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'. - $this->version = '1.3.0'; + $this->version = '1.4.0'; // Url to the file with your last numberversion of this module. //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; @@ -142,7 +142,8 @@ public function __construct($db) 'sessionlist', 'meetinglist', 'trainingsessionlist', - 'auditlist' + 'auditlist', + 'contractlist' ], // Set this to 1 if features of module are opened to external users. 'moduleforexternal' => 1, @@ -221,6 +222,8 @@ public function __construct($db) $i++ => ['DOLIMEET_VERSION','chaine', $this->version, '', 0, 'current'], $i++ => ['DOLIMEET_DB_VERSION', 'chaine', $this->version, '', 0, 'current'], $i++ => ['DOLIMEET_SHOW_PATCH_NOTE', 'integer', 1, '', 0, 'current'], + $i++ => ['DOLIMEET_EMAIL_TEMPLATE_SET', 'integer', 0, '', 0, 'current'], + $i++ => ['DOLIMEET_EMAIL_TEMPLATE_SATISFACTION_SURVEY', 'integer', 0, '', 0, 'current'], // CONST GENERAL CONST. $i++ => ['CONTACT_SHOW_EMAIL_PHONE_TOWN_SELECTLIST', 'integer', 1, '', 0, 'current'], @@ -549,7 +552,7 @@ public function __construct($db) */ public function init($options = ''): int { - global $conf, $langs; + global $conf, $langs, $user; // Permissions. $this->remove($options); @@ -579,24 +582,55 @@ public function init($options = ''): int addDocumentModel('completioncertificatedocument_odt', 'trainingsessiondocument', 'ODT templates', 'DOLIMEET_COMPLETIONCERTIFICATEDOCUMENT_ADDON_ODT_PATH'); addDocumentModel('completioncertificatedocument_odt', 'completioncertificatedocument', 'ODT templates', 'DOLIMEET_COMPLETIONCERTIFICATEDOCUMENT_ADDON_ODT_PATH'); + if (getDolGlobalInt('DOLIMEET_EMAIL_TEMPLATE_SET') == 0 && isModEnabled('digiquali') && version_compare(getDolGlobalString('DIGIQUALI_VERSION'), '1.11.0', '>=')) { + // Load Saturne libraries + require_once __DIR__ . '/../../../saturne/class/saturnemail.class.php'; + + $saturneMail = new SaturneMail($this->db, 'contrat'); + + $position = 100; + $satisfactionSurveys = ['customer', 'billing', 'trainee', 'sessiontrainer', 'opco']; + foreach ($satisfactionSurveys as $satisfactionSurvey) { + $saturneMail->entity = 0; + $saturneMail->type_template = 'contract'; + $saturneMail->lang = 'fr_FR'; + $saturneMail->datec = $this->db->idate(dol_now()); + $saturneMail->label = $langs->transnoentities('SatisfactionSurveyLabel', $langs->transnoentities(ucfirst($satisfactionSurvey))); + $saturneMail->position = $position; + $saturneMail->enabled = "isModEnabled('contrat')"; + $saturneMail->topic = $langs->transnoentities('SatisfactionSurveyTopic', dol_strtolower($langs->transnoentities(ucfirst($satisfactionSurvey)))); + $saturneMail->joinfiles = 1; + $saturneMail->content = $langs->transnoentities('SatisfactionSurveyContent', dol_strtolower($langs->transnoentities(ucfirst($satisfactionSurvey)))); + + $emailTemplateSatisfactionSurvey[$satisfactionSurvey] = $saturneMail->create($user); + $position += 10; + } + + dolibarr_set_const($this->db, 'DOLIMEET_EMAIL_TEMPLATE_SATISFACTION_SURVEY', json_encode($emailTemplateSatisfactionSurvey), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($this->db, 'DOLIMEET_EMAIL_TEMPLATE_SET', 1, 'integer', 0, '', $conf->entity); + } + // Create extrafields during init. require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; $extraFields = new ExtraFields($this->db); - $extraFields->update('label', $langs->transnoentities('Label'), 'varchar', '', 'contrat', 0, 0, 1040, '', '', '', 1); - $extraFields->addExtraField('label', $langs->transnoentities('Label'), 'varchar', 1040, '', 'contrat', 0, 0, '', '', '', '', 1); + $extraFields->update('label', 'Label', 'varchar', 255, 'contrat', 0, 0, $this->numero . 1, '', '', '', 1, '', '', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')", 0, 0, ['css' => 'minwidth100 maxwidth300 widthcentpercentminusxx']); + $extraFields->addExtraField('label', 'Label', 'varchar', $this->numero . 1, 255, 'contrat', 0, 0, '', '', '', '', 1, '', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')", 0, 0, ['css' => 'minwidth100 maxwidth300 widthcentpercentminusxx']); + + $extraFields->update('trainingsession_type', 'TrainingSessionType', 'sellist', '', 'contrat', 0, 0, $this->numero . 10, 'a:1:{s:7:"options";a:1:{s:34:"c_trainingsession_type:label:rowid";N;}}', '', '', 1, 'TrainingSessionTypeHelp', '', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')", 0, 0, ['css' => 'minwidth100 maxwidth300 widthcentpercentminusxx']); + $extraFields->addExtraField('trainingsession_type', 'TrainingSessionType', 'sellist', $this->numero . 10, '', 'contrat', 0, 0, '', 'a:1:{s:7:"options";a:1:{s:34:"c_trainingsession_type:label:rowid";N;}}', '', '', 1, 'TrainingSessionTypeHelp', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')", 0, 0, ['css' => 'minwidth100 maxwidth300 widthcentpercentminusxx']); - $extraFields->update('trainingsession_start', $langs->transnoentities('TrainingSessionStart'), 'datetime', '', 'contrat', 0, 0, 1800, '', '', '', 1); - $extraFields->addExtraField('trainingsession_start', $langs->transnoentities('TrainingSessionStart'), 'datetime', 1040, '', 'contrat', 0, 0, '', '', '', '', 1); + $extraFields->update('trainingsession_location', 'TrainingSessionLocation', 'varchar', 255, 'contrat', 0, 0, $this->numero . 20, '', '', '', 1, 'TrainingSessionLocationHelp', '', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')", 0, 0, ['css' => 'minwidth100 maxwidth300 widthcentpercentminusxx']); + $extraFields->addExtraField('trainingsession_location', 'TrainingSessionLocation', 'varchar', $this->numero . 20, 255, 'contrat', 0, 0, '', '', '', '', 1, 'TrainingSessionLocationHelp', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')", 0, 0, ['css' => 'minwidth100 maxwidth300 widthcentpercentminusxx']); - $extraFields->update('trainingsession_end', $langs->transnoentities('TrainingSessionEnd'), 'datetime', '', 'contrat', 0, 0, 1810, '', '', '', 1); - $extraFields->addExtraField('trainingsession_end', $langs->transnoentities('TrainingSessionEnd'), 'datetime', 1040, '', 'contrat', 0, 0, '', '', '', '', 1); + $extraFields->update('trainingsession_start', 'TrainingSessionStart', 'datetime', '', 'contrat', 0, 0, $this->numero . 30, '', '', '', 1, 'TrainingSessionStartHelp', '', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')", 0, 0, ['css' => 'minwidth100 maxwidth300 widthcentpercentminusxx']); + $extraFields->addExtraField('trainingsession_start', 'TrainingSessionStart', 'datetime', $this->numero . 30, '', 'contrat', 0, 0, '', '', '', '', 1, 'TrainingSessionStartHelp', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')", 0, 0, ['css' => 'minwidth100 maxwidth300 widthcentpercentminusxx']); - $extraFields->update('trainingsession_type', $langs->transnoentities('TrainingSessionType'), 'sellist', '', 'contrat', 0, 0, 1830, 'a:1:{s:7:"options";a:1:{s:34:"c_trainingsession_type:label:rowid";N;}}', '', '', 1); - $extraFields->addExtraField('trainingsession_type', $langs->transnoentities('TrainingSessionType'), 'sellist', 1830, '', 'contrat', 0, 0, '', 'a:1:{s:7:"options";a:1:{s:34:"c_trainingsession_type:label:rowid";N;}}', '', '', 1); + $extraFields->update('trainingsession_end', 'TrainingSessionEnd', 'datetime', '', 'contrat', 0, 0, $this->numero . 40, '', '', '', 1, 'TrainingSessionEndHelp', '', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')"); + $extraFields->addExtraField('trainingsession_end', 'TrainingSessionEnd', 'datetime', $this->numero . 40, '', 'contrat', 0, 0, '', '', '', '', 'TrainingSessionEndHelp', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')"); - $extraFields->update('trainingsession_location', $langs->transnoentities('TrainingSessionLocation'), 'varchar', '', 'contrat', 0, 0, 1850, '', '', '', 1); - $extraFields->addExtraField('trainingsession_location', $langs->transnoentities('TrainingSessionLocation'), 'varchar', 1850, '', 'contrat', 0, 0, '', '', '', '', 1); + $extraFields->update('trainingsession_durations', 'TrainingSessionDurations', 'int', '', 'contrat', 0, 0, $this->numero . 50, '', '', '', 1, 'TrainingSessionDurationHelp', '', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')"); + $extraFields->addExtraField('trainingsession_durations', 'TrainingSessionDurations', 'int', $this->numero . 50, '', 'contrat', 0, 0, '', '', '', '', 1, 'TrainingSessionDurationHelp', '', 0, 'dolimeet@dolimeet', "isModEnabled('dolimeet') && isModEnabled('contrat')"); return $this->_init($sql, $options); } diff --git a/core/substitutions/functions_dolimeet.lib.php b/core/substitutions/functions_dolimeet.lib.php index 203ae84..e6ff000 100644 --- a/core/substitutions/functions_dolimeet.lib.php +++ b/core/substitutions/functions_dolimeet.lib.php @@ -34,7 +34,7 @@ */ function dolimeet_completesubstitutionarray(array &$substitutionarray, Translate $langs, $object) { - global $conf, $db; + global $conf, $db, $user; if ($object->element == 'contrat') { // Load Saturne libraries @@ -62,7 +62,7 @@ function dolimeet_completesubstitutionarray(array &$substitutionarray, Translate foreach ($signatories as $signatory) { $substitutionarray['__DOLIMEET_CONTRACT_TRAININGSESSION_INFOS__'] .= ''; @@ -80,5 +80,50 @@ function dolimeet_completesubstitutionarray(array &$substitutionarray, Translate $substitutionarray['__DOLIMEET_CONTRACT_TRAININGSESSION_END__'] = $object->array_options['options_trainingsession_end']; $substitutionarray['__DOLIMEET_CONTRACT_TRAININGSESSION_TYPE__'] = $object->array_options['options_trainingsession_type']; $substitutionarray['__DOLIMEET_CONTRACT_TRAININGSESSION_LOCATION__'] = $object->array_options['options_trainingsession_location']; + + if (isModEnabled('digiquali') && version_compare(getDolGlobalString('DIGIQUALI_VERSION'), '1.11.0', '>=')) { + // Load DigiQuali libraries + require_once __DIR__ . '/../../../digiquali/class/survey.class.php'; + + $survey = new Survey($db); + + $confEmailTemplateSatisfactionSurvey = json_decode(getDolGlobalString('DOLIMEET_EMAIL_TEMPLATE_SATISFACTION_SURVEY'), true); + $emailModelSelected = GETPOST('modelmailselected', 'int'); + $key = array_search($emailModelSelected, $confEmailTemplateSatisfactionSurvey); + + if ($key !== false) { + $contacts = array_merge($object->liste_contact(-1, 'internal', 0, dol_strtoupper($key)), $object->liste_contact(-1, 'external', 0, dol_strtoupper($key))); + } + + $object->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0); + if (!empty($contacts)) { + foreach ($contacts as $contact) { + if (isset($object->linkedObjectsIds['digiquali_survey']) && !empty($object->linkedObjectsIds['digiquali_survey'])) { + $surveyIDs = $object->linkedObjectsIds['digiquali_survey']; + arsort($surveyIDs); + foreach ($surveyIDs as $surveyID) { + $confName = 'DOLIMEET_' . $contact['code'] . '_SATISFACTION_SURVEY_SHEET'; + $filter = ' AND e.fk_sheet = ' . $conf->global->$confName; + if (getDolGlobalInt($confName) > 0) { + if ($signatory->checkSignatoryHasObject($surveyID, $survey->table_element, $contact['id'], $contact['source'] == 'internal' ? 'user' : 'socpeople', $filter)) { + $survey->fetch($surveyID); + $signatory->fetch($signatory->id); + $substitutionarray['__DOLIMEET_CONTRACT_SURVEY_INFOS__'] .= '
' . dol_strtoupper($signatory->lastname) . ' ' . ucfirst($signatory->firstname) . ''; + if (is_array($sessions) && !empty($sessions)) { + foreach ($sessions as $session) { + $substitutionarray['__DOLIMEET_CONTRACT_SURVEY_INFOS__'] .= ''; + } + $publicAnswerUrl = dol_buildpath('custom/digiquali/public/public_answer.php?track_id=' . $survey->track_id . '&object_type=' . $survey->element . '&document_type=SurveyDocument&entity=' . $conf->entity, 3); + $substitutionarray['__DOLIMEET_CONTRACT_SURVEY_INFOS__'] .= '' . $langs->transnoentities('FillSatisfactionSurvey', dol_strtolower($langs->transnoentities(ucfirst(dol_strtolower($contact['code']))))) . '
'; + } + break; + } + } + } + } + } + } + } } } diff --git a/core/triggers/interface_99_modDoliMeet_DoliMeetTriggers.class.php b/core/triggers/interface_99_modDoliMeet_DoliMeetTriggers.class.php index 6542e93..32f907f 100644 --- a/core/triggers/interface_99_modDoliMeet_DoliMeetTriggers.class.php +++ b/core/triggers/interface_99_modDoliMeet_DoliMeetTriggers.class.php @@ -47,7 +47,7 @@ public function __construct(DoliDB $db) $this->name = preg_replace('/^Interface/i', '', get_class($this)); $this->family = 'demo'; $this->description = 'DoliMeet triggers.'; - $this->version = '1.3.0'; + $this->version = '1.4.0'; $this->picto = 'dolimeet@dolimeet'; } @@ -219,7 +219,7 @@ public function runTrigger($action, $object, User $user, Translate $langs, Conf break; case 'CONTRAT_ADD_CONTACT' : - if (isset($object->array_options['options_trainingsession_type']) && !empty($object->array_options['options_trainingsession_type']) && isModEnabled('digiquali') && getDolGlobalString('DIGIQUALI_VERSION') >= '1.11.0') { + if (isset($object->array_options['options_trainingsession_type']) && !empty($object->array_options['options_trainingsession_type']) && isModEnabled('digiquali') && version_compare(getDolGlobalString('DIGIQUALI_VERSION'), '1.11.0', '>=')) { require_once __DIR__ . '/../../lib/dolimeet_function.lib.php'; if (GETPOST('userid')) { diff --git a/langs/en_US/dolimeet.lang b/langs/en_US/dolimeet.lang index 57bbc19..1bf8623 100644 --- a/langs/en_US/dolimeet.lang +++ b/langs/en_US/dolimeet.lang @@ -115,6 +115,14 @@ AttendantsFromContract = Contract attendants TrainingSessionStartErrorMatchingDate = Error: consistency of course start dates.
The start date of the contract is not equal to the start date of the first training session %s. TrainingSessionEndErrorMatchingDate = Error: consistency of course end dates.
The end date of the training contract is not equal to the end date of the last training session %s. TrainingSessionDurations = Duration of training sessions +TrainingSessionStartHelp = Start date of the first training session of the contract +TrainingSessionEndHelp = End date of the last training session of the contract +TrainingSessionTypeHelp = Type of training session linked to the contract +TrainingSessionLocationHelp = Place where the training session linked to the contract took place +TrainingSessionDurationHelp = Total duration of the sessions HH:MM (ex: 60:30)
The duration shown on the certificate corresponds to the total number of hours of sessions attended by a trainee. +CalculatedTotalSessionDuration = Total calculated duration time: +TrainingSessionDurationErrorMatching = Error: consistency of training session duration.
The total duration of the sessions indicated in the contract is different from the calculated duration of all the sessions linked to the contract. +NoCertificateBecauseAbsent = No certificate was generated for %s %s because it was absent from all sessions. # Attendant role diff --git a/langs/fr_FR/dolimeet.lang b/langs/fr_FR/dolimeet.lang index 20bb094..c33a4fc 100644 --- a/langs/fr_FR/dolimeet.lang +++ b/langs/fr_FR/dolimeet.lang @@ -124,11 +124,18 @@ SessionTrainerResponsible = Responsable du dispensateur de formation SessionTrainerResponsibleDesc = Définit le responsable du dispensateur de formation SessionTrainerResponsibleIdSet = Responsable du dispensateur de formation défini : %s LinkDolimeet_trainsess = Activer le lien avec les sessions de formation -LinkDolimeet_trainsessDescription = Permet la liaison entre les sessions de formations et les modèles de contrôle +LinkDolimeet_trainsessDescription = Permet la liaison entre les sessions de formations et les modèles TrainingSessionStartErrorMatchingDate = Erreur : cohérence des dates de début de la formation.
La date de début de la formation du contrat n'est pas égale à la date début de la première session de formation %s. TrainingSessionEndErrorMatchingDate = Erreur : cohérence des dates de fin de la formation.
La date de fin de la formation du contrat n'est pas égale à la date fin de la dernière session de formation %s. TrainingSessionDurations = Durée des sessions de formation - +TrainingSessionStartHelp = Date de début de la première session de formation du contrat +TrainingSessionEndHelp = Date de fin de la dernière session de formation du contrat +TrainingSessionTypeHelp = Type de formation liée au contrat +TrainingSessionLocationHelp = Lieu où s'est réalisé la formation liée au contrat +TrainingSessionDurationHelp = Durée totale des sessions HH:MM (ex: 60:30)
La durée affichée sur le certificat correspond aux heures additionnées des sessions où un stagiaire a été présent. +CalculatedTotalSessionDuration = Durée totale calculée : +TrainingSessionDurationErrorMatching = Erreur : cohérence de la durée des sessions de formation.
La durée totale des sessions indiqué dans le contrat est différente de la durée calculé de l'ensemble des sessions liées au contrat. +NoCertificateBecauseAbsent = Aucun certificat n'a été généré pour %s %s parcequ'il a été absent à toute les sessions. # Attendant role - Rôle participant @@ -215,6 +222,15 @@ AttendancePresentAuditRate = Taux de présence aux audits AttendanceDelayAuditRate = Taux de retard aux audits AttendanceAbsentAuditRate = Taux d'absence aux audits +# +# Email - Email +# + +# Data - Donnée +SatisfactionSurveyLabel = Questionnaire_Satisfaction_%s +SatisfactionSurveyTopic = [__[MAIN_INFO_SOCIETE_NOM]__] Remise des liens de questionnaire de satisfaction %s pour la convention de formation __REF__ +SatisfactionSurveyContent = Bonjour,

Nous vous envoyons ce mail afin de vous mettre au courant des questionnaires de satisfaction %s liées avec votre convention de formation "__REF__" - "__DOLIMEET_CONTRACT_LABEL__".
Ci-dessous, vous trouverez un aperçu des questionnaires, incluant les détails pertinents :

__DOLIMEET_CONTRACT_SURVEY_INFOS__

Nous vous prions de bien vouloir transmettre ces liens aux parties concernées.
Nous restons à votre disposition pour toute information supplémentaire.

Bien cordialement,

__USER_FULLNAME__
__USER_EMAIL__
__MYCOMPANY_NAME__
__MYCOMPANY_FULLADDRESS__
__MYCOMPANY_EMAIL__ + # @@ -231,3 +247,7 @@ SignAttendanceSheetOnline = Signer la feuille de présence en ligne SetSatisfactionSurvey = Créer enquête de satisfaction NeedToSetSatisfactionSurvey = Configuration de l'enquête de satisfaction %s requise DefineSessionTrainerResponsible = Vous devez définir le responsable du dispensateur de formation dans la configuration de DoliMeet. +FillSatisfactionSurvey = Remplir l'enquête de satisfaction %s +Sessiontrainer = Formateur +Billing = Commanditaire +Customer = Client diff --git a/view/session/session_list.php b/view/session/session_list.php index 86db1f8..46e15a1 100644 --- a/view/session/session_list.php +++ b/view/session/session_list.php @@ -460,8 +460,9 @@ if (!empty($fromType) && !$error) { saturne_get_fiche_head($objectLinked, 'sessionList', $langs->trans($objectType)); - //TODO Shownav must be 0 because navigation between fromObject can't be done while saturne_banner_tab not fix - saturne_banner_tab($objectLinked, 'ref', $moreHtml, 0); + + $moreParams['bannerTab'] = '&fromtype='. $fromType . '&object_type=trainingsession'; + saturne_banner_tab($objectLinked, 'fromid', $moreHtml, 1, 'rowid', 'ref', '', false, $moreParams); } $arrayofselected = is_array($toselect) ? $toselect : [];