From 38f082dde54c8b8ba7c91c7340bee4d8021654d8 Mon Sep 17 00:00:00 2001 From: Guillaume Heurtier <guillaume.heurtier@maarch.org> Date: Fri, 23 Oct 2020 17:53:25 +0200 Subject: [PATCH] FEAT #12018 TIME 7:00 show delegate in visa/opinion circuit --- migration/20.10/2010.sql | 2 + .../controllers/ActionMethodController.php | 30 +++++++---- .../controllers/ListInstanceController.php | 51 +++++++++++++++---- .../models/ListInstanceModelAbstract.php | 3 +- .../controllers/SummarySheetController.php | 30 ++++++++--- .../app/avis/avis-workflow.component.html | 5 ++ .../app/visa/visa-workflow.component.html | 5 ++ src/lang/lang-en.json | 3 +- src/lang/lang-fr.json | 4 +- 9 files changed, 102 insertions(+), 31 deletions(-) diff --git a/migration/20.10/2010.sql b/migration/20.10/2010.sql index 1a78526a13c..0b0b50e6109 100755 --- a/migration/20.10/2010.sql +++ b/migration/20.10/2010.sql @@ -310,6 +310,8 @@ DROP TYPE IF EXISTS custom_fields_modes; CREATE TYPE custom_fields_modes AS ENUM ('form', 'technical'); ALTER TABLE custom_fields ADD COLUMN mode custom_fields_modes NOT NULL DEFAULT 'form'; +ALTER TABLE listinstance ADD COLUMN delegate INTEGER; + /* RE CREATE VIEWS */ CREATE OR REPLACE VIEW res_view_letterbox AS SELECT r.res_id, diff --git a/src/app/action/controllers/ActionMethodController.php b/src/app/action/controllers/ActionMethodController.php index 6b472990c17..389526557de 100644 --- a/src/app/action/controllers/ActionMethodController.php +++ b/src/app/action/controllers/ActionMethodController.php @@ -381,7 +381,7 @@ class ActionMethodController ValidatorModel::intVal($args, ['resId']); $listInstance = ListInstanceModel::get([ - 'select' => ['listinstance_id'], + 'select' => ['listinstance_id', 'item_id'], 'where' => ['res_id = ?', 'difflist_type = ?', 'process_date is null'], 'data' => [$args['resId'], 'VISA_CIRCUIT'], 'orderBy' => ['listinstance_id'], @@ -391,10 +391,13 @@ class ActionMethodController return ['errors' => ['No available circuit']]; } + $set = ['process_date' => 'CURRENT_TIMESTAMP']; + if ($listInstance[0]['item_id'] != $GLOBALS['id']) { + $set['delegate'] = $GLOBALS['id']; + } + ListInstanceModel::update([ - 'set' => [ - 'process_date' => 'CURRENT_TIMESTAMP' - ], + 'set' => $set, 'where' => ['listinstance_id = ?'], 'data' => [$listInstance[0]['listinstance_id']] ]); @@ -724,6 +727,8 @@ class ActionMethodController } $currentStep = $currentStep[0]; + $set = ['process_date' => 'CURRENT_TIMESTAMP']; + $message = null; if ($currentStep['item_id'] != $GLOBALS['id']) { $currentUser = UserModel::getById(['select' => ['firstname', 'lastname'], 'id' => $GLOBALS['id']]); @@ -738,12 +743,12 @@ class ActionMethodController . $currentUser['firstname'] . ' ' . $currentUser['lastname'] . " " . _INSTEAD_OF . " " . $stepUser['firstname'] . ' ' . $stepUser['lastname']; + + $set['delegate'] = $GLOBALS['id']; } ListInstanceModel::update([ - 'set' => [ - 'process_date' => 'CURRENT_TIMESTAMP' - ], + 'set' => $set, 'where' => ['listinstance_id = ?'], 'data' => [$currentStep['listinstance_id']] ]); @@ -761,7 +766,7 @@ class ActionMethodController ValidatorModel::intVal($args, ['resId']); $currentStep = ListInstanceModel::get([ - 'select' => ['listinstance_id'], + 'select' => ['listinstance_id', 'item_id'], 'where' => ['res_id = ?', 'difflist_type = ?', 'item_id = ?', 'item_mode in (?)'], 'data' => [$args['resId'], 'entity_id', $GLOBALS['id'], ['avis', 'avis_copy', 'avis_info']], 'limit' => 1 @@ -772,10 +777,13 @@ class ActionMethodController } $currentStep = $currentStep[0]; + $set = ['process_date' => 'CURRENT_TIMESTAMP']; + if ($currentStep['item_id'] != $GLOBALS['id']) { + $set['delegate'] = $GLOBALS['id']; + } + ListInstanceModel::update([ - 'set' => [ - 'process_date' => 'CURRENT_TIMESTAMP' - ], + 'set' => $set, 'where' => ['listinstance_id = ?'], 'data' => [$currentStep['listinstance_id']] ]); diff --git a/src/app/entity/controllers/ListInstanceController.php b/src/app/entity/controllers/ListInstanceController.php index 84429c09f80..aadc007c2fa 100755 --- a/src/app/entity/controllers/ListInstanceController.php +++ b/src/app/entity/controllers/ListInstanceController.php @@ -69,10 +69,20 @@ class ListInstanceController return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']); } - $listInstances = ListInstanceModel::getVisaCircuitByResId(['select' => ['listinstance_id', 'sequence', 'item_id', 'item_type', 'firstname as item_firstname', 'lastname as item_lastname', 'entity_label as item_entity', 'viewed', 'process_date', 'process_comment', 'signatory', 'requested_signature'], 'id' => $aArgs['resId']]); + $listInstances = ListInstanceModel::getVisaCircuitByResId(['select' => ['listinstance_id', 'sequence', 'item_id', 'item_type', 'firstname as item_firstname', 'lastname as item_lastname', 'entity_label as item_entity', 'viewed', 'process_date', 'process_comment', 'signatory', 'requested_signature', 'delegate'], 'id' => $aArgs['resId']]); foreach ($listInstances as $key => $value) { + $user = UserModel::getById(['id' => $value['item_id'], 'select' => ['status']]); + $listInstances[$key]['isValid'] = !empty($user) && !in_array($user['status'], ['SPD', 'DEL']); + $listInstances[$key]['item_type'] = 'user'; - $listInstances[$key]['labelToDisplay'] = $listInstances[$key]['item_firstname'].' '.$listInstances[$key]['item_lastname']; + $itemLabel = $listInstances[$key]['item_firstname'].' '.$listInstances[$key]['item_lastname']; + + $listInstances[$key]['labelToDisplay'] = $itemLabel; + $listInstances[$key]['delegatedBy'] = null; + if (!empty($listInstances[$key]['delegate'])) { + $listInstances[$key]['labelToDisplay'] = UserModel::getLabelledUserById(['id' => $listInstances[$key]['delegate']]); + $listInstances[$key]['delegatedBy'] = $itemLabel; + } $listInstances[$key]['hasPrivilege'] = true; if (empty($value['process_date']) && !PrivilegeController::hasPrivilege(['privilegeId' => 'visa_documents', 'userId' => $value['item_id']]) && !PrivilegeController::hasPrivilege(['privilegeId' => 'sign_document', 'userId' => $value['item_id']])) { @@ -89,10 +99,20 @@ class ListInstanceController return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']); } - $listInstances = ListInstanceModel::getAvisCircuitByResId(['select' => ['listinstance_id', 'sequence', 'item_id', 'item_type', 'firstname as item_firstname', 'lastname as item_lastname', 'entity_label as item_entity', 'viewed', 'process_date', 'process_comment'], 'id' => $aArgs['resId']]); + $listInstances = ListInstanceModel::getAvisCircuitByResId(['select' => ['listinstance_id', 'sequence', 'item_id', 'item_type', 'firstname as item_firstname', 'lastname as item_lastname', 'entity_label as item_entity', 'viewed', 'process_date', 'process_comment', 'delegate'], 'id' => $aArgs['resId']]); foreach ($listInstances as $key => $value) { + $user = UserModel::getById(['id' => $value['item_id'], 'select' => ['status']]); + $listInstances[$key]['isValid'] = !empty($user) && !in_array($user['status'], ['SPD', 'DEL']); + $listInstances[$key]['item_type'] = 'user'; - $listInstances[$key]['labelToDisplay'] = $listInstances[$key]['item_firstname'].' '.$listInstances[$key]['item_lastname']; + $itemLabel = $listInstances[$key]['item_firstname'].' '.$listInstances[$key]['item_lastname']; + + $listInstances[$key]['labelToDisplay'] = $itemLabel; + $listInstances[$key]['delegatedBy'] = null; + if (!empty($listInstances[$key]['delegate'])) { + $listInstances[$key]['labelToDisplay'] = UserModel::getLabelledUserById(['id' => $listInstances[$key]['delegate']]); + $listInstances[$key]['delegatedBy'] = $itemLabel; + } $listInstances[$key]['hasPrivilege'] = true; if (empty($value['process_date']) && !PrivilegeController::hasPrivilege(['privilegeId' => 'avis_documents', 'userId' => $value['item_id']])) { @@ -109,10 +129,20 @@ class ListInstanceController return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']); } - $listInstances = ListInstanceModel::getParallelOpinionByResId(['select' => ['listinstance_id', 'sequence', 'item_mode', 'item_id', 'item_type', 'firstname as item_firstname', 'lastname as item_lastname', 'entity_label as item_entity', 'viewed', 'process_date', 'process_comment'], 'id' => $aArgs['resId']]); + $listInstances = ListInstanceModel::getParallelOpinionByResId(['select' => ['listinstance_id', 'sequence', 'item_mode', 'item_id', 'item_type', 'firstname as item_firstname', 'lastname as item_lastname', 'entity_label as item_entity', 'viewed', 'process_date', 'process_comment', 'delegate'], 'id' => $aArgs['resId']]); foreach ($listInstances as $key => $value) { + $user = UserModel::getById(['id' => $value['item_id'], 'select' => ['status']]); + $listInstances[$key]['isValid'] = !empty($user) && !in_array($user['status'], ['SPD', 'DEL']); + $listInstances[$key]['item_type'] = 'user'; - $listInstances[$key]['labelToDisplay'] = $listInstances[$key]['item_firstname'].' '.$listInstances[$key]['item_lastname']; + $itemLabel = $listInstances[$key]['item_firstname'].' '.$listInstances[$key]['item_lastname']; + + $listInstances[$key]['labelToDisplay'] = $itemLabel; + $listInstances[$key]['delegatedBy'] = null; + if (!empty($listInstances[$key]['delegate'])) { + $listInstances[$key]['labelToDisplay'] = UserModel::getLabelledUserById(['id' => $listInstances[$key]['delegate']]); + $listInstances[$key]['delegatedBy'] = $itemLabel; + } $listInstances[$key]['hasPrivilege'] = true; if (empty($value['process_date']) && !PrivilegeController::hasPrivilege(['privilegeId' => 'avis_documents', 'userId' => $value['item_id']])) { @@ -272,7 +302,8 @@ class ListInstanceController 'process_date' => null, 'process_comment' => null, 'requested_signature' => false, - 'viewed' => empty($instance['viewed']) ? 0 : $instance['viewed'] + 'viewed' => empty($instance['viewed']) ? 0 : $instance['viewed'], + 'delegate' => $instance['delegate'] ?? null ]); if ($instance['item_mode'] == 'dest') { @@ -417,7 +448,8 @@ class ListInstanceController 'item_mode' => $listInstance['item_mode'], 'process_date' => null, 'process_comment' => $listInstance['process_comment'] ?? null, - 'requested_signature' => $listInstance['requested_signature'] ?? false + 'requested_signature' => $listInstance['requested_signature'] ?? false, + 'delegate' => $listInstance['delegate'] ?? null ]; } @@ -432,7 +464,8 @@ class ListInstanceController 'difflist_type' => $args['type'] == 'visaCircuit' ? 'VISA_CIRCUIT' : 'AVIS_CIRCUIT', 'process_date' => $listInstance['process_date'], 'process_comment' => $listInstance['process_comment'], - 'requested_signature' => $listInstance['requested_signature'] + 'requested_signature' => $listInstance['requested_signature'], + 'delegate' => $listInstance['delegate'] ]); } } diff --git a/src/app/entity/models/ListInstanceModelAbstract.php b/src/app/entity/models/ListInstanceModelAbstract.php index 5941db189bb..921c870ae0f 100755 --- a/src/app/entity/models/ListInstanceModelAbstract.php +++ b/src/app/entity/models/ListInstanceModelAbstract.php @@ -57,7 +57,8 @@ abstract class ListInstanceModelAbstract 'difflist_type' => $args['difflist_type'], 'process_date' => $args['process_date'], 'process_comment' => $args['process_comment'], - 'requested_signature' => empty($args['requested_signature']) ? 'false' : 'true' + 'requested_signature' => empty($args['requested_signature']) ? 'false' : 'true', + 'delegate' => $args['delegate'] ?? null ] ]); diff --git a/src/app/resource/controllers/SummarySheetController.php b/src/app/resource/controllers/SummarySheetController.php index 07ab102f64b..2b7bd50cc7d 100755 --- a/src/app/resource/controllers/SummarySheetController.php +++ b/src/app/resource/controllers/SummarySheetController.php @@ -585,8 +585,16 @@ class SummarySheetController if ($found && $listInstance['res_id'] != $resource['res_id']) { break; } elseif ($listInstance['res_id'] == $resource['res_id']) { + $mode = $listInstance['requested_signature'] ? 'Signataire' : 'Viseur'; + $userLabel = UserModel::getLabelledUserById(['id' => $listInstance['item_id']]) . " ({$mode}) "; + + $delegate = !empty($listInstance['delegate']) ? UserModel::getLabelledUserById(['id' => $listInstance['delegate']]) : ''; + if (!empty($delegate)) { + $userLabel = $delegate . ' ' . _INSTEAD_OF . ' ' . $userLabel; + } + $users[] = [ - 'user' => UserModel::getLabelledUserById(['id' => $listInstance['item_id']]), + 'user' => $userLabel, 'mode' => $listInstance['requested_signature'] ? 'Signataire' : 'Viseur', 'date' => TextFormatModel::formatDate($listInstance['process_date']), ]; @@ -608,7 +616,7 @@ class SummarySheetController $pdf->Cell($specialWidth * 3, 20, _USERS, 1, 0, 'L', false); $pdf->Cell($specialWidth, 20, _ACTION_DATE, 1, 1, 'L', false); foreach ($users as $keyUser => $user) { - $pdf->Cell($specialWidth * 3, 20, $keyUser + 1 . ". {$user['user']} ({$user['mode']})", 1, 0, 'L', false); + $pdf->Cell($specialWidth * 3, 20, $keyUser + 1 . ". {$user['user']}", 1, 0, 'L', false); $pdf->Cell($specialWidth, 20, $user['date'], 1, 1, 'L', false); } } @@ -619,13 +627,19 @@ class SummarySheetController if ($found && $listInstance['res_id'] != $resource['res_id']) { break; } elseif ($listInstance['res_id'] == $resource['res_id']) { - $user = UserModel::getById(['id' => $listInstance['item_id'], 'select' => ['id', 'firstname', 'lastname']]); - $entity = UserModel::getPrimaryEntityById(['id' => $user['id'], 'select' => ['entities.entity_label']]); + $user = UserModel::getLabelledUserById(['id' => $listInstance['item_id']]); + $entity = UserModel::getPrimaryEntityById(['id' => $listInstance['item_id'], 'select' => ['entities.entity_label']]); + + $userLabel = $user . " (" . $entity['entity_label'] . ")"; + $delegate = !empty($listInstance['delegate']) ? UserModel::getLabelledUserById(['id' => $listInstance['delegate']]) : ''; + + if (!empty($delegate)) { + $userLabel = $delegate . ' ' . _INSTEAD_OF . ' ' . $userLabel; + } - $userLabel = $user['firstname'] . ' ' .$user['lastname'] . " (" . $entity['entity_label'] . ")"; $users[] = [ 'user' => $userLabel, - 'date' => TextFormatModel::formatDate($listInstance['process_date']), + 'date' => TextFormatModel::formatDate($listInstance['process_date']) ]; unset($args['data']['listInstancesOpinion'][$listKey]); $found = true; @@ -763,14 +777,14 @@ class SummarySheetController } } elseif ($unit['unit'] == 'opinionWorkflow') { $data['listInstancesOpinion'] = ListInstanceModel::get([ - 'select' => ['item_id', 'process_date', 'res_id'], + 'select' => ['item_id', 'process_date', 'res_id', 'delegate'], 'where' => ['difflist_type = ?', 'res_id in (?)'], 'data' => ['AVIS_CIRCUIT', $tmpIds], 'orderBy' => ['listinstance_id'] ]); } elseif ($unit['unit'] == 'visaWorkflow') { $data['listInstancesVisa'] = ListInstanceModel::get([ - 'select' => ['item_id', 'requested_signature', 'process_date', 'res_id'], + 'select' => ['item_id', 'requested_signature', 'process_date', 'res_id', 'delegate'], 'where' => ['difflist_type = ?', 'res_id in (?)'], 'data' => ['VISA_CIRCUIT', $tmpIds], 'orderBy' => ['listinstance_id'] diff --git a/src/frontend/app/avis/avis-workflow.component.html b/src/frontend/app/avis/avis-workflow.component.html index 3e8f03782b3..f4a8dc7f0cf 100644 --- a/src/frontend/app/avis/avis-workflow.component.html +++ b/src/frontend/app/avis/avis-workflow.component.html @@ -68,6 +68,11 @@ <div class="workflowLineContainer"> <div class="workflowLineLabel" [class.unauthorized]="!diffusion.hasPrivilege || !diffusion.isValid"> {{diffusion.labelToDisplay}} + <ng-container *ngIf="diffusion.process_date != null && diffusion.delegatedBy !== null"> + <mat-icon mat-list-icon class="fas fa-exclamation-circle" + [title]="this.translate.instant('lang.insteadOf') + ' ' + diffusion.delegatedBy" + style="opacity:0.5;font-size: 125%;height: 15px"></mat-icon> + </ng-container> </div> <div class="workflowLineSubLabel" [class.unauthorized]="!diffusion.hasPrivilege || !diffusion.isValid"> {{diffusion.item_entity}} diff --git a/src/frontend/app/visa/visa-workflow.component.html b/src/frontend/app/visa/visa-workflow.component.html index 2413157e94a..d1268ddcbe2 100755 --- a/src/frontend/app/visa/visa-workflow.component.html +++ b/src/frontend/app/visa/visa-workflow.component.html @@ -83,6 +83,11 @@ <div class="workflowLineContainer"> <div class="workflowLineLabel" [class.unauthorized]="!diffusion.hasPrivilege || !diffusion.isValid"> {{diffusion.labelToDisplay}} + <ng-container *ngIf="diffusion.process_date != null && diffusion.delegatedBy !== null"> + <mat-icon mat-list-icon class="fas fa-exclamation-circle" + [title]="this.translate.instant('lang.insteadOf') + ' ' + diffusion.delegatedBy" + style="opacity:0.5;font-size: 125%;height: 15px"></mat-icon> + </ng-container> </div> <div class="workflowLineSubLabel" [class.unauthorized]="!diffusion.hasPrivilege || !diffusion.isValid"> {{diffusion.item_entity}} diff --git a/src/lang/lang-en.json b/src/lang/lang-en.json index 1ec76ab1a1a..4fa681ef9c9 100644 --- a/src/lang/lang-en.json +++ b/src/lang/lang-en.json @@ -2078,5 +2078,6 @@ "displayCriteria": "Show search criteria", "displaySelectedValues": "Show selected values", "quickSearch": "Quick search", - "contactInput": "Contact input" + "contactInput": "Contact input", + "insteadOf": "Instead of" } diff --git a/src/lang/lang-fr.json b/src/lang/lang-fr.json index efd31d6c07c..24a79b73d6b 100644 --- a/src/lang/lang-fr.json +++ b/src/lang/lang-fr.json @@ -2130,5 +2130,7 @@ "installNewCustom": "Créer une nouvelle instance", "mustConnectToInstall" : "Veuillez vous connecter pour accéder à l'installeur", "mustPrivilegeToInstall" : "Vous n'avez pas le droit de créer une nouvelle instance", - "instancesList" : "Instances présentes" + "instancesList" : "Instances présentes", + "insteadOf": "À la place de" + } -- GitLab