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
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
@@ -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';
13 changes: 13 additions & 0 deletions class/control.class.php
Original file line number Diff line number Diff line change
@@ -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'],
@@ -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.
*/
@@ -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);

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
@@ -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,
@@ -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
5 changes: 4 additions & 1 deletion core/tpl/digiquali_answers.tpl.php
Original file line number Diff line number Diff line change
@@ -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">
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
@@ -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);
2 changes: 1 addition & 1 deletion css/digiquali.min.css
41 changes: 41 additions & 0 deletions css/scss/page/_control.scss
Original file line number Diff line number Diff line change
@@ -178,3 +178,44 @@
.confirmquestions input[readonly]:hover {
cursor: default;
}
.verdict-container {
display: flex;
gap: 10px;
justify-content: center;
}

.verdict-option input[type="radio"] {
display: none;
}

.verdict-box {
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid transparent;
border-radius: 5px;
font-weight: bold;
cursor: pointer;
transition: background-color 0.3s, border-color 0.3s;
}

.verdict-ok {
background-color: #e0f7e9;
color: #27ae60;
}

.verdict-ko {
background-color: #fdecea;
color: #c0392b;
}

.verdict-option input[type="radio"]:checked + .verdict-box {
border-color: #000;
}

.verdict-box.disabled {
cursor: not-allowed;
opacity: 0.5;
}
Binary file not shown.
2 changes: 1 addition & 1 deletion js/digiquali.min.js

Large diffs are not rendered by default.

258 changes: 258 additions & 0 deletions js/modules/control.js
Original file line number Diff line number Diff line change
@@ -32,11 +32,27 @@ window.digiquali.control.event = function() {
$( document ).on( 'change', '#fk_sheet', window.digiquali.control.showSelectObjectLinked);
$( document ).on( 'click', '.clipboard-copy', window.digiquali.control.copyToClipboard );
$( document ).on( 'change', '#productId', window.digiquali.control.refreshLotSelector );
$( document ).on( 'change', '[name="mass_control"]', window.digiquali.control.showSubControlsModel );
$( document ).on( 'click', '.switch-public-control-view', window.digiquali.control.switchPublicControlView );
$(document).on('click', '.show-only-questions-with-no-answer', window.digiquali.control.showOnlyQuestionsWithNoAnswer);
$(document).on('click', '.photo-sheet-category', window.digiquali.control.getSheetCategoryID);
$(document).on('click', '.photo-sheet-sub-category', window.digiquali.control.getSheetSubCategoryID);
$(document).on('click', '.photo-sheet', window.digiquali.control.getSheetID);
$(document).on('click', '.saveSubControl:not(.butActionRefused)', window.digiquali.control.saveSubControl);
$(document).on('click', '.validateSubControl:not(.butActionRefused)', window.digiquali.control.validateSubControl);
$(document).on('click', '.reopenSubControl:not(.butActionRefused)', window.digiquali.control.reopenSubControl);
$(document).on('click', '.lockSubControl:not(.butActionRefused)', window.digiquali.control.lockSubControl);
$(document).on('click', '.saveSubControlAnswers', window.digiquali.control.saveSubControlAnswers);
$(document).ready(function() {
$('.verdict-box').on('click', function(event) {
if ($(this).hasClass('disabled')) {
event.stopPropagation();
event.preventDefault();
}
});
});


};

/**
@@ -311,3 +327,245 @@ window.digiquali.control.getSheetID = function() {
error: function() {}
});
};

/**
* Save sub control
*
* @since 1.15.0
* @version 1.15.0
*
* @return {void}
*/
window.digiquali.control.saveSubControl = function() {
let subControlID = $(this).attr('data-control-id');
let mainControlId = $(this).attr('data-main-control-id');
let notePublic = $(this).closest('.table-row').find('.note-public').val();

let questionIds = [];
$(this).closest('.table-row').find('.select-answer').each(function() {
let questionId = $(this).attr('data-questionid');

let answer = $(this).find('.question-answer').val();
let comment = $(this).closest('.wpeo-table').find('.question-comment').val();

questionIds[questionId] = {
'answer': answer,
'comment': comment
};
});

let verdict = $(this).closest('.table-row').find('.verdict-option input[type="radio"]:checked').val();
let token = window.saturne.toolbox.getToken();

window.saturne.loader.display($(this).closest('.table-row'));
let url = document.URL.replace(/id=\d+/, 'id=' + subControlID);
$.ajax({
url: url + '&token=' + token + '&action=confirm_setVerdict&verdict=' + verdict + '&noteControl=' + notePublic,
type: 'POST',
processData: false,
contentType: false,
data: [],
success: async function(resp) {
for (const [questionId, answer] of Object.entries(questionIds)) {
let url = document.URL.replace(/id=\d+/, 'id=' + subControlID);
await window.digiquali.object.saveAnswer(questionId, answer.answer, answer.comment, url + '&action=save&token=' + token);
}

let url = document.URL.replace(/id=\d+/, 'id=' + mainControlId);
$.ajax({
url: url,
type: 'GET',
processData: false,
contentType: false,
data: [],
success: function (resp) {
$('.wpeo-loader').removeClass('wpeo-loader')
$('.sub-control-' + subControlID).replaceWith($(resp).find('.sub-control-' + subControlID));
}
});
},
error: function() {}
});
}

/**
* Lock sub control
*
* @since 1.15.0
* @version 1.15.0
*
* @return {void}
*/
window.digiquali.control.lockSubControl = function() {
let subControlID = $(this).attr('data-control-id');
let mainControlId = $(this).attr('data-main-control-id');
let token = window.saturne.toolbox.getToken();

window.saturne.loader.display($(this).closest('.table-row'));

let url = document.URL.replace(/id=\d+/, 'id=' + subControlID);
$.ajax({
url: url + '&token=' + token + '&action=confirm_lock',
type: 'POST',
processData: false,
contentType: false,
data: [],
success: function () {
let url = document.URL.replace(/id=\d+/, 'id=' + mainControlId);
$.ajax({
url: url,
type: 'GET',
processData: false,
contentType: false,
data: [],
success: function (resp) {
$('.sub-control-' + subControlID).replaceWith($(resp).find('.sub-control-' + subControlID));
}
});
},
error: function () {
}
});
}

/**
* Validate sub control
*
* @since 1.15.0
* @version 1.15.0
*
* @return {void}
*/
window.digiquali.control.validateSubControl = function() {
let subControlID = $(this).attr('data-control-id');
let mainControlId = $(this).attr('data-main-control-id');
let token = window.saturne.toolbox.getToken();

window.saturne.loader.display($(this).closest('.table-row'));

let url = document.URL.replace(/id=\d+/, 'id=' + subControlID);
$.ajax({
url: url + '&token=' + token + '&action=confirm_validate&confirm=yes',
type: 'POST',
processData: false,
contentType: false,
data: [],
success: function () {
let url = document.URL.replace(/id=\d+/, 'id=' + mainControlId);
$.ajax({
url: url,
type: 'GET',
processData: false,
contentType: false,
data: [],
success: function (resp) {
$('.sub-control-' + subControlID).replaceWith($(resp).find('.sub-control-' + subControlID));
}
});
},
error: function () {
}
});
}

/**
* Reopen sub control
*
* @since 1.15.0
* @version 1.15.0
*
* @return {void}
*/
window.digiquali.control.reopenSubControl = function() {
let subControlID = $(this).attr('data-control-id');
let mainControlId = $(this).attr('data-main-control-id');
let token = window.saturne.toolbox.getToken();

window.saturne.loader.display($(this).closest('.table-row'));

let url = document.URL.replace(/id=\d+/, 'id=' + subControlID);
$.ajax({
url: url + '&token=' + token + '&action=confirm_set_reopen&confirm=yes',
type: 'POST',
processData: false,
contentType: false,
data: [],
success: function () {
let url = document.URL.replace(/id=\d+/, 'id=' + mainControlId);
$.ajax({
url: url,
type: 'GET',
processData: false,
contentType: false,
data: [],
success: function (resp) {
$('.sub-control-' + subControlID).replaceWith($(resp).find('.sub-control-' + subControlID));
}
});
},
error: function () {
}
});
}

/**
* Save sub control answers
*
* @since 1.15.0
* @version 1.15.0
*
* @return {void}
*/
window.digiquali.control.saveSubControlAnswers = async function() {
let subControlID = $(this).attr('data-control-id');
let mainControlId = $(this).attr('data-main-control-id');

window.saturne.loader.display($(this));

let questionIds = [];
$(this).closest('.table-row').find('.select-answer').each(function () {
let questionId = $(this).attr('data-questionid');

let answer = $(this).find('.question-answer').val();
let comment = $(this).closest('.wpeo-table').find('.question-comment').val();

questionIds[questionId] = {
'answer': answer,
'comment': comment
};
});

let token = window.saturne.toolbox.getToken();

let url = document.URL.replace(/id=\d+/, 'id=' + subControlID);

for (const [questionId, answer] of Object.entries(questionIds)) {
await window.digiquali.object.saveAnswer(questionId, answer.answer, answer.comment, url + '&action=save&token=' + token);
}

url = document.URL.replace(/id=\d+/, 'id=' + mainControlId);
$.ajax({
url: url,
type: 'GET',
processData: false,
contentType: false,
data: [],
success: function (resp) {
$('.sub-control-' + subControlID).replaceWith($(resp).find('.sub-control-' + subControlID));
$('.wpeo-loader').removeClass('wpeo-loader');
}
});
}

/**
* Show sub controls model
*
* @since 1.15.0
* @version 1.15.0
*
* @return {void}
*/
window.digiquali.control.showSubControlsModel = function() {
$('.sub-controls-model').attr('style', '');
$('.sub-controls-model').find('.select2-container').css('width', '500px')
}
35 changes: 22 additions & 13 deletions js/modules/object.js
Original file line number Diff line number Diff line change
@@ -63,6 +63,7 @@ window.digiquali.object.event = function() {
$(document).on( 'click', '.answer:not(.disable)', window.digiquali.object.selectAnswer);
$(document).on( 'input', '.input-answer:not(.disable)', window.digiquali.object.selectAnswer);
$(document).on( 'keyup', '.question-comment', window.digiquali.object.showCommentUnsaved);
$(document).on( 'click', '.verdict-box', window.digiquali.object.updateButtonsStatus);
};

/**
@@ -103,6 +104,7 @@ window.digiquali.object.selectAnswer = function() {
let answer = '';
let answerValue = $(this).hasClass('answer') ? $(this).attr('value') : $(this).val();
let comment = $(this).closest('.table-id-' + questionId).find('#comment' + questionId).val();
let controlId = $(this).closest('.table-id-' + questionId).attr('data-control-id');
if ($(this).closest('.table-cell').hasClass('select-answer')) {
if ($(this).hasClass('multiple-answers')) {
$(this).closest('span').toggleClass('active');
@@ -130,7 +132,7 @@ window.digiquali.object.selectAnswer = function() {
if (!publicInterface && autoSave == 1 && !$(this).hasClass('multiple-answers')) {
window.digiquali.object.saveAnswer(questionId, answer, comment);
} else {
window.digiquali.object.updateButtonsStatus();
window.digiquali.object.updateButtonsStatus(controlId);
}
};

@@ -158,16 +160,16 @@ window.digiquali.object.showCommentUnsaved = function() {
*
* @return {void}
*/
window.digiquali.object.updateButtonsStatus = function() {
$('#saveButton').removeClass('butActionRefused');
$('#saveButton').addClass('butAction');
$('#saveButton').css('background', '#0d8aff');
window.digiquali.object.updateButtonsStatus = function(controlId) {
controlId = stringIsInteger(controlId) ? controlId : $(this).attr('data-control-id');
$('#saveButton' + controlId).removeClass('butActionRefused');
$('#saveButton' + controlId).addClass('butAction');
$('.fa-circle').css('display', 'inline');
$('#saveButton').attr('onclick','$("#saveObject").submit()');
$('#saveButton' + controlId).attr('onclick','$("#saveObject'+controlId+'").submit()');

$('.validateButton').removeClass('butAction');
$('#dialog-confirm-actionButtonValidate').removeAttr('id');
$('.validateButton').addClass('butActionRefused');
$('.validateButton' + controlId).removeClass('butAction');
$('#dialog-confirm-actionButtonValidate' + controlId).removeAttr('id');
$('.validateButton' + controlId).addClass('butActionRefused');
};

/**
@@ -179,15 +181,20 @@ window.digiquali.object.updateButtonsStatus = function() {
* @param {int} questionId Question ID
* @param {string} answer Answer value
* @param {string} comment Comment value
* @param {string} customUrl URL to save answer
* @return {void}
*/
window.digiquali.object.saveAnswer = function(questionId, answer, comment) {
window.digiquali.object.saveAnswer = function(questionId, answer, comment, customUrl = '') {
let token = window.saturne.toolbox.getToken();
let querySeparator = window.saturne.toolbox.getQuerySeparator(document.URL);
window.saturne.loader.display($('.table-id-' + questionId));
let url = customUrl ? customUrl : document.URL + querySeparator + 'action=save&token=' + token

if (customUrl.length < 1) {
window.saturne.loader.display($('.table-id-' + questionId));
}

$.ajax({
url: document.URL + querySeparator + 'action=save&token=' + token,
url: url,
type: 'POST',
data: JSON.stringify({
autoSave: true,
@@ -198,7 +205,9 @@ window.digiquali.object.saveAnswer = function(questionId, answer, comment) {
processData: false,
contentType: false,
success: function(resp) {
$('.fiche').replaceWith($(resp).find('.fiche'));
if (customUrl.length < 1) {
$('.fiche').replaceWith($(resp).find('.fiche'));
}
},
error: function() {}
});
15 changes: 15 additions & 0 deletions langs/fr_FR/digiquali.lang
Original file line number Diff line number Diff line change
@@ -349,6 +349,17 @@ QuestionAnswered = Réponse/Question
LastStatusDate = Dernières dates de statut
ValidationDate = Date de validation
ReOpenDate = Date de réouverture
MassControl = Contrôle en masse
LinkedControlList = Liste des contrôles liés
NewMassControl = Nouveau contrôle en masse
ControlledObject = Objet contrôlé
SubControlSheet = Modèle des sous-contrôles
AddAnObjectToControl = Ajouter un objet à contrôler
SubControlsMustBeLockedToSetVerdict = Les sous-contrôles doivent être verrouillés pour définir le verdict
MainControlMustBeDraftToEditSubControls = Le contrôle principal doit être brouillon pour éditer les sous-contrôles
ParentControl = Contrôle parent
NoSubControlFound = Aucun sous-contrôle trouvé


#
# ControlDet
@@ -362,6 +373,7 @@ AnswerPhoto = Photo
AutoSaveActionQuestionAnswer = Sauvegarde automatique des réponses aux questions
AutoSaveActionQuestionAnswerDescription = Sauvegarde automatiquement les réponses aux questions lors du choix de la réponse
NoObjectLineAnswersPhoto = Pas de photos sur les réponses du %s
Answers = Réponses

#
# ControlDocument - Fiche de Contrôle
@@ -378,6 +390,8 @@ controldocument = fiche de controle
controldocument.odt = Fiche de Contrôle
controldocument_photo.odt = Fiche de Contrôle avec photos
controldocument_photo = fiche de controle avec photos
masscontroldocument = Fiche de Contrôle en masse
masscontroldocument.odt = Fiche de Contrôle en masse



@@ -441,3 +455,4 @@ Remain = reste
InProgressAndLocked = -- (En cours + verrouillé) --
NoObservations = Pas d'observations
BasedOnModel = Basé sur le modèle
ShowDocument = Afficher le document
2 changes: 1 addition & 1 deletion lib/digiquali_control.lib.php
Original file line number Diff line number Diff line change
@@ -58,5 +58,5 @@ function control_prepare_head(Control $object): array
$moreparam['documentType'] = 'ControlDocument';
$moreparam['attendantTableMode'] = 'simple';

return saturne_object_prepare_head($object, $head, $moreparam, true);
return saturne_object_prepare_head($object, $head, $moreparam, !($object->fk_control > 0));
}
1 change: 1 addition & 0 deletions sql/control/llx_digiquali_control.key.sql
Original file line number Diff line number Diff line change
@@ -21,3 +21,4 @@ ALTER TABLE llx_digiquali_control ADD INDEX idx_digiquali_control_fk_user_contro
ALTER TABLE llx_digiquali_control ADD INDEX idx_digiquali_control_fk_projectid (projectid);
ALTER TABLE llx_digiquali_control ADD UNIQUE INDEX uk_digiquali_control_ref (ref, entity);
ALTER TABLE llx_digiquali_control ADD CONSTRAINT llx_digiquali_control_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid);
ALTER TABLE llx_digiquali_control ADD CONSTRAINT llx_digiquali_control_fk_control FOREIGN KEY (fk_control) REFERENCES llx_digiquali_control(rowid);
2 changes: 2 additions & 0 deletions sql/control/llx_digiquali_control.sql
Original file line number Diff line number Diff line change
@@ -32,6 +32,8 @@ CREATE TABLE llx_digiquali_control(
control_date datetime,
next_control_date datetime,
success_rate double(24,8),
mass_control boolean,
fk_control integer,
fk_user_creat integer NOT NULL,
fk_user_modif integer,
fk_sheet integer NOT NULL,
5 changes: 5 additions & 0 deletions sql/update.sql
Original file line number Diff line number Diff line change
@@ -127,3 +127,8 @@ ALTER TABLE `llx_digiquali_survey` ADD `success_rate` DOUBLE(24,8) NULL AFTER `p

-- 1.13.0
ALTER TABLE `llx_digiquali_control` ADD `label` VARCHAR(255) NULL AFTER `status`;

-- 1.15.0
ALTER TABLE `llx_digiquali_control` ADD `mass_control` BOOLEAN NULL AFTER `success_rate`;
ALTER TABLE `llx_digiquali_control` ADD `fk_control` INTEGER NULL AFTER `mass_control`;
ALTER TABLE llx_digiquali_control ADD CONSTRAINT llx_digiquali_control_fk_control FOREIGN KEY (fk_control) REFERENCES llx_digiquali_control(rowid);
125 changes: 105 additions & 20 deletions view/control/control_card.php
Original file line number Diff line number Diff line change
@@ -90,6 +90,7 @@
$ecmfile = new EcmFiles($db);
$ecmdir = new EcmDirectory($db);
$category = new Categorie($db);
$parentControl = new Control($db);

// View objects
$form = new Form($db);
@@ -151,6 +152,13 @@
$options['photos'] = GETPOST('clone_photos');
if ($object->id > 0) {
$result = $object->createFromClone($user, $object->id, $options);
$subControlList = $object->fetchAll('', '', 0, 0, ['fk_control' => $object->id]);
if (is_array($subControlList) && !empty($subControlList)) {
foreach ($subControlList as $subControl) {
$options['fk_control'] = $result;
$subControl->createFromClone($user, $subControl->id, $options);
}
}
if ($result > 0) {
header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result);
exit();
@@ -167,8 +175,11 @@

if (!empty($linkableElements)) {
foreach ($linkableElements as $linkableElementType => $linkableElement) {
if (!empty(GETPOST($linkableElement['post_name'])) && GETPOST($linkableElement['post_name']) > 0) {
$controlledObjectSelected++;
$post = GETPOST('multi_' . $linkableElement['post_name'], 'array');
if (is_array($post) && !empty($post)) {
foreach($post as $postSingle) {
$controlledObjectSelected++;
}
}
}
}
@@ -221,7 +232,7 @@
if ($action == 'confirm_setVerdict' && $permissiontosetverdict && !GETPOST('cancel', 'alpha')) {
$object->fetch($id);
if (!$error) {
$object->verdict = GETPOST('verdict', 'int');
$object->verdict = GETPOST('verdict', 'int') ?: null;
$object->note_public .= (!empty($object->note_public) ? chr(0x0A) : '') . GETPOST('noteControl');
$result = $object->update($user);
if ($result > 0) {
@@ -260,6 +271,35 @@
}
}

//Action to add sub controls
if ($action == 'mass_control_add_object') {
$object->fetch($id);
$linkableElements = get_sheet_linkable_objects();
$controlledObjectSelected = 0;

if (!empty($linkableElements)) {
foreach ($linkableElements as $linkableElementType => $linkableElement) {
$post = GETPOST($linkableElement['post_name']);
if (!empty($post)) {
$objectType = $linkableElement['link_name'];
$objectId = $post;

$controlToCreate = new Control($db);

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

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

$controlToCreate->add_object_linked($linkableElement['link_name'], $objectId);
}
}
}
}

// Actions confirm_lock, confirm_archive
require_once __DIR__ . '/../../../saturne/core/tpl/actions/object_workflow_actions.tpl.php';

@@ -398,6 +438,20 @@
print '</td></tr>';
}

// Mass control
print '<tr><td>' . ($source != 'pwa' ? $langs->trans('MassControl') : img_picto('', 'fontawesome_fa-tasks_fas_#000000_2em', 'class="pictofixedwidth"')) . '</td><td>';
print ($source != 'pwa' ? img_picto('', 'fontawesome_fa-tasks_fas_#000000', 'class="pictofixedwidth"') : '');
print '<input type="checkbox" name="mass_control" value="1" ' . (GETPOST('mass_control') ? 'checked' : '') . '>';
print '</td></tr>';

//FK SHEET
print '<tr style="'. (GETPOST('mass_control') ? : 'display:none') .'" class="sub-controls-model"><td class="fieldrequired">' . ($source != 'pwa' ? $langs->trans('SubControlSheet') : img_picto('', $sheet->picto . '_2em', 'class="pictofixedwidth"')) . '</td><td>';
print ($source != 'pwa' ? img_picto('', $sheet->picto, 'class="pictofixedwidth"') : '') . $sheet->selectSheetList(GETPOST('fk_sub_controls_sheet'), 'fk_sub_controls_sheet', 's.type = ' . '"' . $object->element . '" AND s.status = ' . Sheet::STATUS_LOCKED);
if ($source != 'pwa') {
print '<a class="butActionNew" href="' . DOL_URL_ROOT . '/custom/digiquali/view/sheet/sheet_card.php?action=create" target="_blank"><span class="fa fa-plus-circle valignmiddle paddingleft" title="' . $langs->trans('AddSheet') . '"></span></a>';
}
print '</td></tr>';

print '</table>';
print '<hr>';

@@ -439,7 +493,7 @@

print '<tr><td class="titlefieldcreate">' . ($source != 'pwa' ? $langs->transnoentities($linkableElement['langs']) : img_picto('', $linkableElement['picto'], 'class="pictofixedwidth fa-3x"')) . '</td><td>';
print($source != 'pwa' ? img_picto('', $linkableElement['picto'], 'class="pictofixedwidth"') : '');
print $form->selectArray($objectPostName, $objectArray, $objectPost, $langs->trans('Select') . ' ' . strtolower($langs->trans($linkableElement['langs'])), 0, 0, '', 0, 0, dol_strlen(GETPOST('fromtype')) > 0 && GETPOST('fromtype') != $linkableElement['link_name'], '', 'maxwidth500 widthcentpercentminusxx');
print $form->multiselectarray('multi_' . $objectPostName, $objectArray, [$objectPost], $langs->trans('Select') . ' ' . strtolower($langs->trans($linkableElement['langs'])), 0, 0, '', 0, 0, dol_strlen(GETPOST('fromtype')) > 0 && GETPOST('fromtype') != $linkableElement['link_name']);
if ($source != 'pwa') {
print '<a class="butActionNew" href="' . DOL_URL_ROOT . '/' . $linkableElement['create_url'] . '?action=create&backtopage=' . urlencode($_SERVER['PHP_SELF'] . '?action=create') . '" target="_blank"><span class="fa fa-plus-circle valignmiddle paddingleft" title="' . $langs->trans('Create') . ' ' . strtolower($langs->trans($linkableElement['langs'])) . '"></span></a>';
}
@@ -521,7 +575,7 @@
}

$questionConfirmInfo .= '<br><br><b>' . $langs->trans('ConfirmValidateControl') . '</b>';
$formConfirm .= $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('ValidateControl'), $questionConfirmInfo, 'confirm_validate', '', 'yes', 'actionButtonValidate', 250);
$formConfirm .= $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('ValidateControl'), $questionConfirmInfo, 'confirm_validate', '', 'yes', 'actionButtonValidate' . $object->id, 250);
}

// Draft confirmation
@@ -604,6 +658,15 @@
print $form->editfieldval('NextControlDate', 'next_control_date', $object->next_control_date, $object, $permissiontoadd && $object->status < Control::STATUS_LOCKED, 'datepicker', '', null, null, "id=$object->id");
print '</td>';

if ($object->fk_control > 0) {
print '<tr class="field_parent_control"><td class="titlefield fieldname_parent_control">';
print $langs->trans('ParentControl');
print '</td><td class="valuefield fieldname_parent_control">';
$parentControl->fetch($object->fk_control);
print $parentControl->getNomUrl(1);
print '</td>';
}

print '<tr class="field_verdict"><td class="titlefield fieldname_verdict">';
print $langs->trans('Verdict');
print '</td><td class="valuefield fieldname_verdict">';
@@ -651,17 +714,14 @@
if ($linkableElement['conf'] > 0 && (!empty($object->linkedObjectsIds[$linkableElement['link_name']]))) {
$className = $linkableElement['className'];
$linkedObject = new $className($db);
print '<tr><td class="titlefield">';
print $langs->trans($linkableElement['langs']);
print '</td>';
print '<td>';

$linkedObjectKey = array_key_first($object->linkedObjectsIds[$linkableElement['link_name']]);
$linkedObjectId = $object->linkedObjectsIds[$linkableElement['link_name']][$linkedObjectKey];
foreach($object->linkedObjectsIds[$linkableElement['link_name']] as $linkedObjectId) {
$linkedObject->fetch($linkedObjectId);

$result = $linkedObject->fetch($linkedObjectId);

if ($result > 0) {
print '<tr><td class="titlefield">';
print $langs->trans($linkableElement['langs']);
print '</td>';
print '<td>';

print $linkedObject->getNomUrl(1);

@@ -672,8 +732,10 @@
print '</strong>';
}

print '<td></tr>';
print '<br/>';
}
print '<td>';
print '</tr>';
}
}

@@ -780,7 +842,7 @@
</div>
<?php }

print '<form method="POST" action="' . $_SERVER['PHP_SELF'] . '?action=save&id=' . $object->id . '" id="saveObject" enctype="multipart/form-data">';
print '<form method="POST" action="' . $_SERVER['PHP_SELF'] . '?action=save&id=' . $object->id . '" id="saveObject'. $object->id .'" enctype="multipart/form-data">';
print '<input type="hidden" name="token" value="' . newToken() . '">';
print '<input type="hidden" name="action" value="save">';

@@ -797,15 +859,15 @@
// Save question answer
$displayButton = $onPhone ? '<i class="fas fa-save fa-2x"></i>' : '<i class="fas fa-save"></i>' . ' ' . $langs->trans('Save');
if ($object->status == Control::STATUS_DRAFT) {
print '<span class="butActionRefused" id="saveButton" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=save' . '">' . $displayButton . ' <i class="fas fa-circle" style="color: red; display: none; ' . ($onPhone ? 'vertical-align: top;' : '') . '"></i></span>';
print '<span class="butActionRefused" id="saveButton'. $object->id .'" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=save' . '">' . $displayButton . ' <i class="fas fa-circle" style="color: red; display: none; ' . ($onPhone ? 'vertical-align: top;' : '') . '"></i></span>';
} else {
print '<span class="butActionRefused classfortooltip" title="' . dol_escape_htmltag($langs->trans('ObjectMustBeDraft', ucfirst($langs->transnoentities('The' . ucfirst($object->element))))) . '">' . $displayButton . '</span>';
}

// Validate
$displayButton = $onPhone ? '<i class="fas fa-check fa-2x"></i>' : '<i class="fas fa-check"></i>' . ' ' . $langs->trans('Validate');
if ($object->status == $object::STATUS_DRAFT && empty($cantValidateControl) && !$equipmentOutdated) {
print '<span class="validateButton butAction" id="actionButtonValidate">' . $displayButton . '</span>';
print '<span class="validateButton validateButton'. $object->id .' butAction" id="actionButtonValidate'. $object->id .'">' . $displayButton . '</span>';
} else if ($cantValidateControl > 0) {
print '<span class="butActionRefused classfortooltip" title="' . dol_escape_htmltag($langs->trans('QuestionMustBeAnswered', $cantValidateControl)) . '">' . $displayButton . '</span>';
} else if ($equipmentOutdated) {
@@ -824,14 +886,29 @@

// Set verdict control
$displayButton = $onPhone ? '<i class="far fa-check-circle fa-2x"></i>' : '<i class="far fa-check-circle"></i>' . ' ' . $langs->trans('SetOK/KO');
if ($object->status == $object::STATUS_VALIDATED && $object->verdict == null && !$equipmentOutdated) {
$permissionToSetVerdict = 1;
if ($object->mass_control == 1) {
$subControlList = $object->fetchAll('', '', 0, 0, ['fk_control' => $object->id, 'status >= 0']);
if (is_array($subControlList) && !empty($subControlList)) {
foreach($subControlList as $subControl) {
if ($subControl->status != $object::STATUS_LOCKED) {
$permissionToSetVerdict = 0;
break;
}
}
}
}

if ($object->status == $object::STATUS_VALIDATED && $object->verdict == null && !$equipmentOutdated && $permissionToSetVerdict) {
if ($permissiontosetverdict) {
print '<span class="butAction" id="actionButtonVerdict">' . $displayButton . '</span>';
}
} elseif ($object->status == $object::STATUS_DRAFT) {
print '<span class="butActionRefused classfortooltip" title="' . dol_escape_htmltag($langs->trans('ControlMustBeValidatedToSetVerdict')) . '">' . $displayButton . '</span>';
} else if ($equipmentOutdated) {
print '<span class="butActionRefused classfortooltip" title="' . dol_escape_htmltag($langs->trans('ControlEquipmentOutdated')) . '">' . $displayButton . '</span>';
} else if(!$permissionToSetVerdict) {
print '<span class="butActionRefused classfortooltip" title="' . dol_escape_htmltag($langs->trans('SubControlsMustBeLockedToSetVerdict')) . '">' . $displayButton . '</span>';
} else {
print '<span class="butActionRefused classfortooltip" title="' . dol_escape_htmltag($langs->trans('ControlVerdictSelected')) . '">' . $displayButton . '</span>';
}
@@ -906,7 +983,7 @@
} ?>
</div>

<?php if (!$user->conf->DIGIQUALI_SHOW_ONLY_QUESTIONS_WITH_NO_ANSWER || $answerCounter != $questionCounter) {
<?php if (!$user->conf->DIGIQUALI_SHOW_ONLY_QUESTIONS_WITH_NO_ANSWER || $answerCounter != $questionCounter) {
print load_fiche_titre($langs->trans('LinkedQuestionsList'), '', '');
print '<div id="tablelines" class="question-answer-container noborder noshadow">';
require_once __DIR__ . '/../../core/tpl/digiquali_answers.tpl.php';
@@ -915,6 +992,11 @@

print '</div>';
print '</form>';

if ($object->mass_control) {
require_once __DIR__ . '/../../core/tpl/digiquali_mass_control_list.tpl.php';
}

print dol_get_fiche_end();

if ($action != 'presend') {
@@ -925,6 +1007,9 @@
$fileDir = $upload_dir . '/' . $dirFiles;
$urlSource = $_SERVER['PHP_SELF'] . '?id=' . $object->id;

$conf->global->DIGIQUALI_CONTROLDOCUMENT_DEFAULT_MODEL = $object->mass_control > 0 ? $conf->global->DIGIQUALI_MASSCONTROLDOCUMENT_DEFAULT_MODEL : $conf->global->DIGIQUALI_CONTROLDOCUMENT_DEFAULT_MODEL;


print saturne_show_documents('digiquali:' . ucfirst($object->element) . 'Document', $dirFiles, $fileDir, $urlSource, $permissiontoadd, $permissiontodelete, $conf->global->DIGIQUALI_CONTROLDOCUMENT_DEFAULT_MODEL, 1, 0, 0, 0, '', '', '', $langs->defaultlang, '', $object, 0, 'remove_file', (($object->status > CONTROL::STATUS_DRAFT) ? 1 : 0), $langs->trans('ObjectMustBeValidatedToGenerate', ucfirst($langs->transnoentities('The' . ucfirst($object->element)))));
print '</div>';

6 changes: 4 additions & 2 deletions view/sheet/sheet_card.php
Original file line number Diff line number Diff line change
@@ -627,9 +627,11 @@
if (empty($reshook) && $permissiontoadd) {
// Create object depending on sheet type
if ($object->status == $object::STATUS_LOCKED) {
print '<a class="butAction" href="' . dol_buildpath('/custom/digiquali/view/' . $object->type . '/' . $object->type . '_card.php?action=create&fk_sheet=' . $object->id, 1) . '"><i class="fas fa-plus-circle"></i> ' . $langs->trans('New' . ucfirst($object->type)) . '</a>';
print '<a class="butAction" href="' . dol_buildpath('/custom/digiquali/view/' . $object->type . '/' . $object->type . '_card.php?action=create&fk_sub_controls_sheet=' . $object->id, 1) . '&mass_control=1"><i class="fas fa-plus-circle"></i> ' . $langs->trans('NewMass' . ucfirst($object->type)) . '</a>';
print '<a class="butAction" href="' . dol_buildpath('/custom/digiquali/view/' . $object->type . '/' . $object->type . '_card.php?action=create&fk_sheet=' . $object->id, 1) . '"><i class="fas fa-plus-circle"></i> ' . $langs->trans('New' . ucfirst($object->type)) . '</a>';
} else {
print '<span class="butActionRefused classfortooltip" title="' . dol_escape_htmltag($langs->trans('ObjectMustBeLocked', ucfirst($langs->transnoentities('The' . ucfirst($object->element))))) . '"><i class="fas fa-plus-circle"></i> ' . $langs->trans('New' . ucfirst($object->type)) . '</span>';
print '<span class="butActionRefused classfortooltip" title="' . dol_escape_htmltag($langs->trans('ObjectMustBeLocked', ucfirst($langs->transnoentities('The' . ucfirst($object->element))))) . '"><i class="fas fa-plus-circle"></i> ' . $langs->trans('NewMass' . ucfirst($object->type)) . '</span>';
print '<span class="butActionRefused classfortooltip" title="' . dol_escape_htmltag($langs->trans('ObjectMustBeLocked', ucfirst($langs->transnoentities('The' . ucfirst($object->element))))) . '"><i class="fas fa-plus-circle"></i> ' . $langs->trans('New' . ucfirst($object->type)) . '</span>';
}

// Modify