Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1680 [Control] add: mass control #1864

Open
wants to merge 25 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
72dbe90
add multi object control
theodaviddd Aug 7, 2024
b1c76bd
#1680 [Control] add: multi control data model
theodaviddd Aug 13, 2024
610c325
#1680 [Control] add: multi control list template
theodaviddd Aug 13, 2024
0980076
#1680 [Control] add: mass control management
theodaviddd Aug 13, 2024
24b3947
#1680 [Control] add: control answers & lock
theodaviddd Aug 13, 2024
5d3133f
#1680 [Control] add: controlled object on mass control list
theodaviddd Aug 13, 2024
4159a25
add: save answers button in modal
evarisk-theo Aug 20, 2024
df7cb27
add multi sheets on control form
evarisk-theo Aug 20, 2024
449d88a
add: add controls to control
evarisk-theo Aug 20, 2024
c0b799b
fix: mass signature
theodaviddd Aug 20, 2024
5123119
fix: action clone
theodaviddd Aug 20, 2024
dde45a6
fix: lock button & js
theodaviddd Aug 16, 2024
da0ed00
fix: workflow
theodaviddd Aug 16, 2024
26b1fde
add: document on list
theodaviddd Aug 16, 2024
4f5ad2a
fix: prevent user from clicking if control is locked
theodaviddd Aug 16, 2024
805b7ec
fix: questions answering
theodaviddd Aug 27, 2024
d624f86
fix: avoid sub controls edition if main control is validated
theodaviddd Aug 27, 2024
26fe14b
fix: show parent control
theodaviddd Aug 27, 2024
2521f83
add: document management
lmag Aug 15, 2024
6d41b05
fix: prevent saving sub control from disabling main control validate …
theodaviddd Sep 3, 2024
6691f09
#1680 [Control] fix: loader on selected answer only
theodaviddd Sep 3, 2024
5bdd7f6
#1680 [Control] fix: change variables from masscontrol to maincontro…
theodaviddd Sep 3, 2024
1b62bc3
#1680 [Control] fix: verdict update if null
theodaviddd Sep 3, 2024
53cb95e
Auto stash before rebase of "add_multi_objects_controls"
theodaviddd Sep 3, 2024
64d3b3b
#1680 [Control] fix: minor typo & syntax changes
theodaviddd Sep 3, 2024
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
21 changes: 21 additions & 0 deletions class/actions_digiquali.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,27 @@ public function doActions(array $parameters, $object, string $action): int
require_once __DIR__ . '/../class/survey.class.php';
}

if (strpos($parameters['context'], 'controlpublicsignature') !== false) {
if ($action == 'add_signature') {
$data = json_decode(file_get_contents('php://input'), true);
$subControlList = $object->fetchAll('', '', 0, 0, ['fk_control' => $object->id]);

if(is_array($subControlList) && !empty($subControlList)) {
foreach ($subControlList as $subControl) {
$signatory = new SaturneSignature($this->db, 'digiquali', 'control');
$signatory->fetch(0, '', ' AND fk_object =' . "'" . $subControl->id . "' AND object_type='control'");
$signatory->signature = $data['signature'];
$signatory->signature_date = dol_now();

$result = $signatory->update($user, true);
if ($result > 0) {
$signatory->setSigned($user, false, 'public');
}
}
}
}
}

if (!$error) {
$this->results = array('myreturn' => 999);
$this->resprints = 'A text to show';
Expand Down
13 changes: 13 additions & 0 deletions class/control.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ class Control extends SaturneObject
'verdict' => ['type' => 'smallint', 'label' => 'Verdict', 'enabled' => 1, 'position' => 110, 'notnull' => 0, 'visible' => 5, 'showinpwa' => 1, 'index' => 1, 'positioncard' => 20, 'arrayofkeyval' => [0 => '', 1 => 'OK', 2 => 'KO', 3 => 'N/A']],
'photo' => ['type' => 'text', 'label' => 'Photo', 'enabled' => 1, 'position' => 120, 'notnull' => 0, 'visible' => 0, 'showinpwa' => 0],
'track_id' => ['type' => 'text', 'label' => 'TrackID', 'enabled' => 1, 'position' => 125, 'notnull' => 0, 'visible' => 2, 'showinpwa' => 0],
'mass_control' => ['type' => 'boolean', 'label' => 'MassControl', 'enabled' => 1, 'position' => 126, 'notnull' => 0, 'visible' => 0, 'showinpwa' => 0],
'fk_control' => ['type' => 'integer:Control:digiquali/class/control.class.php', 'label' => 'Control', 'picto' => 'control', 'enabled' => 1, 'position' => 127, 'notnull' => 0, 'visible' => 0, 'showinpwa' => 0, 'foreignkey' => 'digiquali_control.rowid'],
'fk_user_creat' => ['type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'picto' => 'user', 'enabled' => 1, 'position' => 130, 'notnull' => 1, 'visible' => 0, 'showinpwa' => 0, 'foreignkey' => 'user.rowid'],
'fk_user_modif' => ['type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'picto' => 'user', 'enabled' => 1, 'position' => 140, 'notnull' => 0, 'visible' => 0, 'showinpwa' => 0, 'foreignkey' => 'user.rowid'],
'fk_sheet' => ['type' => 'integer:Sheet:digiquali/class/sheet.class.php', 'label' => 'Sheet', 'picto' => 'fontawesome_fa-list_fas_#d35968', 'enabled' => 1, 'position' => 12, 'notnull' => 1, 'visible' => 5, 'showinpwa' => 0, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'foreignkey' => 'digiquali_sheet.rowid'],
Expand Down Expand Up @@ -235,6 +237,16 @@ class Control extends SaturneObject
*/
public int $fk_sheet;

/**
* @var int Control ID.
*/
public $fk_control;

/**
* @var bool Mass control.
*/
public $mass_control;

/**
* @var int|string|null User ID.
*/
Expand Down Expand Up @@ -586,6 +598,7 @@ public function createFromClone(User $user, int $fromID, array $options): int
}

$object->context = 'createfromclone';
$object->fk_control = $options['fk_control'];

$object->fetchObjectLinked('','', $object->id, 'digiquali_' . $object->element, 'OR', 1, 'sourcetype', 0);

Expand Down

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion core/modules/modDigiQuali.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public function __construct($db)
'main',
'controladmin',
'surveyadmin',
'controlpublicsignature'
],
// Set this to 1 if features of module are opened to external users
'moduleforexternal' => 0,
Expand Down Expand Up @@ -234,7 +235,8 @@ public function __construct($db)
$i++ => ['DIGIQUALI_CONTROLDOCUMENT_ADDON', 'chaine', 'mod_controldocument_standard', '', 0, 'current'],
$i++ => ['DIGIQUALI_CONTROLDOCUMENT_ADDON_ODT_PATH', 'chaine', 'DOL_DOCUMENT_ROOT/custom/digiquali/documents/doctemplates/controldocument/', '', 0, 'current'],
$i++ => ['DIGIQUALI_CONTROLDOCUMENT_CUSTOM_ADDON_ODT_PATH', 'chaine', 'DOL_DATA_ROOT' . (($conf->entity == 1 ) ? '/' : '/' . $conf->entity . '/') . 'ecm/digiquali/controldocument/', '', 0, 'current'],
$i++ => ['DIGIQUALI_CONTROLDOCUMENT_DEFAULT_MODEL', 'chaine', 'template_controldocument_photo' ,'', 0, 'current'],
$i++ => ['DIGIQUALI_CONTROLDOCUMENT_DEFAULT_MODEL', 'chaine', 'template_controldocument_photo' ,'', 0, 'current'],
$i++ => ['DIGIQUALI_MASSCONTROLDOCUMENT_DEFAULT_MODEL', 'chaine', 'template_masscontroldocument' ,'', 0, 'current'],
$i++ => ['DIGIQUALI_DOCUMENT_MEDIA_VIGNETTE_USED', 'chaine', 'small','', 0, 'current'],

//CONST SURVEY DOCUMENT
Expand Down
5 changes: 4 additions & 1 deletion core/tpl/digiquali_answers.tpl.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,20 @@

if (is_array($sheet->linkedObjects['digiquali_question']) && !empty($sheet->linkedObjects['digiquali_question'])) {
foreach ($sheet->linkedObjects['digiquali_question'] as $question) {

$questionAnswer = '';
$comment = '';
$result = $objectLine->fetchFromParentWithQuestion($object->id, $question->id);

if (is_array($result) && !empty($result)) {
$objectLine = array_shift($result);
$questionAnswer = $objectLine->answer;
$comment = $objectLine->comment;
}

if (!$user->conf->DIGIQUALI_SHOW_ONLY_QUESTIONS_WITH_NO_ANSWER or empty($questionAnswer)) {
?>
<div class="wpeo-table table-flex table-3 table-id-<?php echo $question->id ?>" data-publicInterface="<?php echo $publicInterface; ?>" data-autoSave="<?php echo getDolGlobalInt('DIGIQUALI_' . dol_strtoupper($object->element) . 'DET_AUTO_SAVE_ACTION'); ?>">
<div class="wpeo-table table-flex table-3 table-id-<?php echo $question->id ?>" data-control-id="<?php echo $object->id; ?>" data-publicInterface="<?php echo $publicInterface; ?>" data-autoSave="<?php echo getDolGlobalInt('DIGIQUALI_' . dol_strtoupper($object->element) . 'DET_AUTO_SAVE_ACTION'); ?>">
<div class="table-row">
<!-- Contenu et commentaire -->
<div class="table-cell table-full">
Expand Down
175 changes: 175 additions & 0 deletions core/tpl/digiquali_mass_control_list.tpl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<?php

/**
* \file digiquali_mass_control_list.tpl.php
* \ingroup digiquali
* \brief Template for displaying the list of mass controls linked to an object
*/

$subControlList = $object->fetchAll('', '', 0, 0, ['fk_control' => $object->id]);

print '<div class="div-table-responsive-no-min" style="overflow-x: unset !important">';

print load_fiche_titre($langs->trans('LinkedControlList'), '', '');

print '<div class="wpeo-table table-flex table-3">';

$tableHeaders = [
$langs->trans('Name'),
$langs->trans('Status'),
$langs->trans('ControlledObject'),
$langs->trans('Verdict'),
$langs->trans('NoteControl'),
$langs->trans('Answers'),
$langs->trans('Document'),
$langs->trans('Action'),
];

print '<div class="table-row header-row">';
$i = 0;
foreach ($tableHeaders as $header) {
print '<div class="table-cell header-cell '. ($i >= 2 ? 'center' : '').'">' . $header . '</div>';
$i++;
}
print '</div>';

$mainControlId = $object->id;
$sheet = new Sheet($db);
$mainControl = $object;

// Check if there are any mass controls and print them
if (is_array($subControlList) && !empty($subControlList)) {
foreach ($subControlList as $subControl) {
$answersDisabled = $subControl->status == $subControl::STATUS_LOCKED || $mainControl->status >= $mainControl::STATUS_VALIDATED;
$object = $subControl;
$sheet->fetch($subControl->fk_sheet);
$sheet->fetch_optionals();

$sheet->fetchObjectLinked($object->fk_sheet, 'digiquali_' . $sheet->element);
$subControl->fetch_optionals();
$subControl->fetchLines();
$subControl->fetchObjectLinked('', '', $subControl->id, 'digiquali_control', 'OR', 1, 'sourcetype', 0);
$linkableElements = get_sheet_linkable_objects();

print '<div class="table-row sub-control-'. $subControl->id .'">';
print '<div class="table-cell">' . $subControl->getNomUrl(1) . '</div>';
print '<div class="table-cell">' . $subControl->getLibStatut(5) . '</div>';
print '<div class="table-cell maxwidth200">';
foreach ($linkableElements as $linkableElementType => $linkableElement) {
if ($linkableElement['conf'] > 0 && (!empty($object->linkedObjectsIds[$linkableElement['link_name']]))) {
$className = $linkableElement['className'];
$linkedObject = new $className($db);
foreach($object->linkedObjectsIds[$linkableElement['link_name']] as $linkedObjectId) {
$linkedObject->fetch($linkedObjectId);

print $linkedObject->getNomUrl(1, 0, '', 'maxwidth200');

if ($linkedObject->array_options['options_qc_frequency'] > 0) {
print ' ';
print '<strong>';
print $langs->transnoentities('QcFrequency') . ' : ' . $linkedObject->array_options['options_qc_frequency'];
print '</strong>';
}
print '<br/>';
}
}
}
print '</div>';

print '<div class="table-cell center">';
print '<div class="verdict-container">';
print '<label class="verdict-option">';
print '<input type="radio" name="verdict' . $subControl->id . '" value="1" ' . ($subControl->verdict == '1' ? 'checked' : '') . '>';
print '<span class="verdict-box verdict-ok '. ($answersDisabled ? "disabled" : "") .'" data-control-id="'. $subControl->id .'">OK</span>';
print '</label>';
print '<label class="verdict-option">';
print '<input data-control-id="'. $subControl->id .'" type="radio" name="verdict' . $subControl->id . '" value="0" ' . ($subControl->verdict == '0' ? 'checked' : '') . '>';
print '<span class="verdict-box verdict-ko '. ($answersDisabled ? "disabled" : "") .'" data-control-id="'. $subControl->id .'">KO</span>';
print '</label>';
print '</div>';
print '</div>';

print '<div class="table-cell center"><textarea '. ($answersDisabled ? "disabled" : "") .' type="text" class="note-public">' . $subControl->note_public . '</textarea></div>';

print '<div class="table-cell center">';
$questionCounter = 0;
if (!empty($sheet->linkedObjects['digiquali_question'])) {
$questionCounter = count($sheet->linkedObjects['digiquali_question']);
}

$answerCounter = 0;
if (is_array($subControl->lines) && !empty($subControl->lines)) {
foreach ($subControl->lines as $subControlLine) {
if (dol_strlen($subControlLine->answer) > 0) {
$answerCounter++;
}
}
}

print '<span class="answerCounter">' . $answerCounter . '/' . $questionCounter . '</span>';
print '<button type="button" class="'. ($answersDisabled ? "butActionRefused" : "butAction modal-open") .' answerSubControl" data-control-id="'. $subControl->id .'">';
print $langs->trans('Answers');
print '<input type="hidden" class="modal-options" data-modal-to-open="modalSubControl'. $subControl->id .'">';
print '</button>';
print '</div>';

$documenturl = DOL_URL_ROOT . '/document.php';
print '<div class="table-cell center">';
$documentList = dol_dir_list($conf->digiquali->multidir_output[$subControl->entity ?: 1] . '/controldocument/' . $subControl->ref . '/');
if (!empty($documentList)) {
$lastDocument = $documentList[count($documentList) - 1];
$lastDocumentPath = $lastDocument['relativename'];
print '<a class="documentdownload paddingright" href="' . $documenturl . '?modulepart=digiquali&file=controldocument/' . urlencode($subControl->ref . '/' . $lastDocumentPath) . '">';
print '<button type="button" class="wpeo-button button-square-40 button-blue wpeo-tooltip-event" aria-label="' . $langs->trans('ShowDocument') . '"><i class="fas fa-eye button-icon"></i></button>';
print '</a>';
}

print '</div>';
print '<div class="table-cell center">';
if (!$answersDisabled) {
if ($subControl->status == $subControl::STATUS_VALIDATED) {
$displayButton = $onPhone ? '<i class="fas fa-lock fa-2x"></i>' : '<i class="fas fa-lock"></i>' . ' ' . $langs->trans('Lock');
print '<span class="lockSubControl butAction" id="actionButtonLockSubControl" data-control-id="'. $subControl->id .'" data-main-control-id="'. $mainControlId .'">' . $displayButton . '</span>';
$displayButton = $onPhone ? '<i class="fas fa-unlock fa-2x"></i>' : '<i class="fas fa-unlock"></i>' . ' ' . $langs->trans('ReOpenDoli');
print '<span class="reopenSubControl butAction" id="actionButtonReopenSubControl" data-control-id="'. $subControl->id .'" data-main-control-id="'. $mainControlId .'">' . $displayButton . '</span>';
} else {
$validateButtonDisabled = !(dol_strlen($subControl->verdict) && $answerCounter == $questionCounter);
$displayButton = $onPhone ? '<i class="fas fa-check fa-2x"></i>' : '<i class="fas fa-check"></i>' . ' ' . $langs->trans('Validate');
print '<span class="validateSubControl validateButton'. $subControl->id .' butAction'. ($validateButtonDisabled ? 'Refused' : '') .'" id="actionButtonValidateSubControl" data-control-id="'. $subControl->id .'" data-main-control-id="'. $mainControlId .'">' . $displayButton . '</span>';
$displayButton = $onPhone ? '<i class="fas fa-save fa-2x"></i>' : '<i class="fas fa-save"></i>' . ' ' . $langs->trans('Save');
print '<span class="saveSubControl butAction'. (!$validateButtonDisabled ? 'Refused' : '') .'" id="saveButton'. $subControl->id .'" data-control-id="'. $subControl->id .'" data-main-control-id="'. $mainControlId .'">' . $displayButton . '</span>';
}
} else if ($subControl->status != $subControl::STATUS_LOCKED) {
print $langs->trans('MainControlMustBeDraftToEditSubControls');
} else {
print '';
}

print '</div>';

print '<div class="wpeo-modal" id="modalSubControl'. $subControl->id .'">';
print '<div class="modal-container">';
print '<div class="modal-content">';
print load_fiche_titre($langs->trans('LinkedQuestionsList') . ' - ' . $subControl->getNomUrl(1), '', '');
$conf->global->DIGIQUALI_CONTROLDET_AUTO_SAVE_ACTION = 0;
print '<div id="tablelines" class="question-answer-container noborder noshadow">';
require __DIR__ . '/../../core/tpl/digiquali_answers.tpl.php';
print '</div>';
print '</div>';
print '<div class="modal-footer">';
$displayButton = $onPhone ? '<i class="fas fa-save fa-2x"></i>' : '<i class="fas fa-save"></i>' . ' ' . $langs->trans('Save');
print '<span class="saveSubControlAnswers butAction" id="actionButtonSaveSubControlAnswer" data-control-id="'. $subControl->id .'" data-main-control-id="'. $mainControlId .'">' . $displayButton . '</span>';
print '</div>';
print '</div>';
print '</div>';
print '</div>';
}
} else {
print '<div class="table-row">';
print '<div class="table-cell" colspan="6">' . $langs->trans('NoSubControlFound') . '</div>';
print '</div>';
}

$object->fetch($mainControlId);

?>
Original file line number Diff line number Diff line change
Expand Up @@ -131,28 +131,54 @@ public function runTrigger($action, $object, User $user, Translate $langs, Conf
case 'CONTROL_CREATE' :
// Load Digiquali libraries
require_once __DIR__ . '/../../class/sheet.class.php';
require_once __DIR__ . '/../../class/control.class.php';

// Load Saturne libraries.
require_once __DIR__ . '/../../../saturne/class/saturnesignature.class.php';

$sheet = new Sheet($this->db);
$signatory = new SaturneSignature($this->db, 'digiquali');

$sheet->fetch($object->fk_sheet);
if ($sheet->success_rate > 0) {
$object->success_rate = $sheet->success_rate;
$object->setValueFrom('success_rate', $object->success_rate, '', '', 'text', '', $user);
}

$elementArray = [];
$isMassControl = $object->mass_control;

if ($object->context != 'createfromclone') {
$elementArray = get_sheet_linkable_objects();
$elementArray = get_sheet_linkable_objects();

if (!empty($elementArray)) {
foreach ($elementArray as $linkableElementType => $linkableElement) {
if (!empty(GETPOST($linkableElement['post_name'])) && GETPOST($linkableElement['post_name']) > 0) {
$object->add_object_linked($linkableElement['link_name'], GETPOST($linkableElement['post_name']));
foreach ($elementArray as $linkableElement) {
$post = GETPOST('multi_' . $linkableElement['post_name'], 'array');
if (!empty($post) && $post > 0) {

foreach($post as $postElement) {
if ($isMassControl) {
$control = new Control($this->db);

$control->status = $control::STATUS_DRAFT;
$control->label = $object->label;
$control->fk_sheet = GETPOST('fk_sub_controls_sheet');
$control->fk_user_controller = $object->fk_user_controller;
$control->fk_control = $object->id;

$controlId = $control->create($user, true);

$control->fetch($controlId);
$control->add_object_linked($linkableElement['link_name'], $postElement);

$signatory->setSignatory($control->id, $control->element, 'user', [$control->fk_user_controller], 'Controller', 1);
} else {
$object->add_object_linked($linkableElement['link_name'], $postElement);
}
}
}
}
}

// Load Saturne libraries.
require_once __DIR__ . '/../../../saturne/class/saturnesignature.class.php';

$signatory = new SaturneSignature($this->db, 'digiquali');
$signatory->setSignatory($object->id, $object->element, 'user', [$object->fk_user_controller], 'Controller', 1);
Expand Down
Loading