From 51f3706c9461e2f4c07c30a52d13cafcf7ca95eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9l=C3=A8ne=20Meneuvrier?= Date: Tue, 12 Mar 2024 16:11:47 +0100 Subject: [PATCH 01/11] add rapport and photos visites #2198 --- .../form_upload_documents.js | 164 +++++++++++++----- .../Back/SignalementFileController.php | 9 + src/Security/Voter/InterventionVoter.php | 5 +- .../view/photos-documents.html.twig | 2 +- .../visites-modal-upload-files.html.twig | 73 ++++++++ .../visites/modals/visites-modals.html.twig | 3 + .../view/visites/visite-item.html.twig | 14 -- .../view/visites/visites-buttons.html.twig | 69 ++++++-- .../view/visites/visites-list.html.twig | 2 +- 9 files changed, 262 insertions(+), 79 deletions(-) create mode 100644 templates/back/signalement/view/visites/modals/visites-modal-upload-files.html.twig diff --git a/assets/controllers/back_signalement_view/form_upload_documents.js b/assets/controllers/back_signalement_view/form_upload_documents.js index 674a3163a..a81b5cada 100644 --- a/assets/controllers/back_signalement_view/form_upload_documents.js +++ b/assets/controllers/back_signalement_view/form_upload_documents.js @@ -1,19 +1,59 @@ -const modalUploadFiles = document?.querySelector('#fr-modal-upload-files') -if (modalUploadFiles) { - const dropArea = document.querySelector('.modal-upload-drop-section') - const listContainer = document.querySelector('.modal-upload-list') - const fileSelector = document.querySelector('.modal-upload-files-selector') - const fileSelectorInput = document.querySelector('.modal-upload-files-selector-input') - const addFileRoute = modalUploadFiles.dataset.addFileRoute - const addFileToken = modalUploadFiles.dataset.addFileToken - const waitingSuiviRoute = modalUploadFiles.dataset.waitingSuiviRoute - const deleteTmpFileRoute = modalUploadFiles.dataset.deleteTmpFileRoute - const selectTypeToClone = document.querySelector('#select-type-to-clone') - const selectDesordreToClone = document.querySelector('#select-desordre-to-clone') - const editFileRoute = modalUploadFiles.dataset.editFileRoute - const editFileToken = modalUploadFiles.dataset.editFileToken - const ancre = document.querySelector('#modal-upload-file-dynamic-content') - const btnValidate = document.querySelector('#btn-validate-modal-upload-files') +initializeUploadModal( + '#fr-modal-upload-files', + '.modal-upload-drop-section', + '.modal-upload-list', + '.modal-upload-files-selector', + '.modal-upload-files-selector-input', + '#select-type-to-clone', + '#select-desordre-to-clone', + '#btn-validate-modal-upload-files', + '#modal-upload-file-dynamic-content' +); + +document?.querySelectorAll('.fr-modal-visites-upload-files')?.forEach(modalVisiteUpload => { + initializeUploadModal( + '#'+modalVisiteUpload.id, + '.modal-upload-drop-section', + '.modal-upload-list', + '.modal-upload-files-selector', + '.modal-upload-files-selector-input', + null, + null, + '#btn-validate-modal-upload-files', + '#modal-upload-file-dynamic-content' + ) +}) + + +function initializeUploadModal( + modalSelector, + fileDropAreaSelector, + fileListContainerSelector, + fileTypeSelector, + fileInputSelector, + selectTypeToCloneSelector, + selectDesordreToCloneSelector, + btnValidateSelector, + ancreSelector +) { + const modal = document?.querySelector(modalSelector); + if (!modal) return; + + const dropArea = modal.querySelector(fileDropAreaSelector); + const listContainer = modal.querySelector(fileListContainerSelector); + const fileSelector = modal.querySelector(fileTypeSelector) + const fileSelectorInput = modal.querySelector(fileInputSelector) + const addFileRoute = modal.dataset.addFileRoute; + const addFileToken = modal.dataset.addFileToken; + const waitingSuiviRoute = modal.dataset.waitingSuiviRoute; + const deleteTmpFileRoute = modal.dataset.deleteTmpFileRoute; + const selectTypeToClone = selectTypeToCloneSelector ? modal.querySelector(selectTypeToCloneSelector) : null; + const selectDesordreToClone = selectDesordreToCloneSelector ? modal.querySelector(selectDesordreToCloneSelector) : null; + const editFileRoute = modal.dataset.editFileRoute; + const editFileToken = modal.dataset.editFileToken; + const btnValidate = modal.querySelector(btnValidateSelector); + const ancre = modal.querySelector(ancreSelector); + fileSelector.onclick = () => fileSelectorInput.click() fileSelectorInput.onchange = () => { @@ -81,7 +121,7 @@ if (modalUploadFiles) { listContainer.prepend(div) let http = new XMLHttpRequest() let data = new FormData() - if (modalUploadFiles.dataset.fileType == 'photo') { + if (modal.dataset.fileType == 'photo') { data.append('signalement-add-file[photos][]', file) } else { data.append('signalement-add-file[documents][]', file) @@ -98,20 +138,46 @@ if (modalUploadFiles) { let btnDeleteTmpFile = div.querySelector('a.delete-tmp-file') addEventListenerDeleteTmpFile(btnDeleteTmpFile) if (this.status == 200) { - modalUploadFiles.dataset.hasChanges = true - if (modalUploadFiles.dataset.fileType == 'photo') { - var clone = selectDesordreToClone.cloneNode(true) - clone.id = 'select-desordre-' + response.response + modal.dataset.hasChanges = true + if (null !== selectDesordreToClone || null !== selectTypeToClone){ + let clone + if (modal.dataset.fileType == 'photo') { + clone = selectDesordreToClone.cloneNode(true) + clone.id = 'select-desordre-' + response.response + } else { + clone = selectTypeToClone.cloneNode(true) + clone.id = 'select-type-' + response.response + } + clone.dataset.fileId = response.response + if (clone.querySelectorAll('option').length == 1) { + clone.remove() + } else { + div.querySelector('.select-container').appendChild(clone) + addEventListenerSelectTypeDesordre(clone) + } } else { - var clone = selectTypeToClone.cloneNode(true) - clone.id = 'select-type-' + response.response - } - clone.dataset.fileId = response.response - if (clone.querySelectorAll('option').length == 1) { - clone.remove() - } else { - div.querySelector('.select-container').appendChild(clone) - addEventListenerSelectTypeDesordre(clone) + if (null !== modal.dataset.documentType){ + let httpEdit = new XMLHttpRequest() + let dataEdit = new FormData() + dataEdit.append('file_id', response.response) + dataEdit.append('documentType', modal.dataset.documentType) + dataEdit.append('interventionId', modal.dataset.interventionId) + + dataEdit.append('_token', editFileToken) + httpEdit.onreadystatechange = function () { + if (this.readyState == XMLHttpRequest.DONE) { + let response = JSON.parse(this.response) + if (this.status != 200) { + let parent = fileListContainerSelector + parent.querySelector('.file-error').innerHTML = '
' + response.response + '
' + } + } + } + httpEdit.open('POST', editFileRoute, true) + httpEdit.setRequestHeader("X-Requested-With", "XMLHttpRequest") + httpEdit.send(dataEdit) + } + } btnDeleteTmpFile.href = btnDeleteTmpFile.href.replace('REPLACE', response.response) btnDeleteTmpFile.classList.remove('fr-hidden', 'delete-html') @@ -127,8 +193,8 @@ if (modalUploadFiles) { } function initInnerHtml(file) { - var innerHTML =`
`; - if (modalUploadFiles.dataset.fileType == 'photo') { + let innerHTML =`
`; + if (modal.dataset.fileType == 'photo') { innerHTML += `
@@ -164,7 +230,7 @@ if (modalUploadFiles) { let http = new XMLHttpRequest() let data = new FormData() data.append('file_id', selectField.dataset.fileId) - if (modalUploadFiles.dataset.fileType == 'photo') { + if (modal.dataset.fileType == 'photo') { data.append('documentType', 'PHOTO_SITUATION') data.append('desordreSlug', selectField.value) } else { @@ -207,8 +273,8 @@ if (modalUploadFiles) { } - modalUploadFiles.addEventListener('dsfr.conceal', (e) => { - if (modalUploadFiles.dataset.validated == "true" && modalUploadFiles.dataset.hasChanges == "true") { + modal.addEventListener('dsfr.conceal', (e) => { + if (modal.dataset.validated == "true" && modal.dataset.hasChanges == "true") { fetch(waitingSuiviRoute).then((response) => { window.location.reload() }) @@ -217,37 +283,41 @@ if (modalUploadFiles) { document.querySelectorAll('a.delete-tmp-file').forEach((button) => { button.click() }) - modalUploadFiles.dataset.hasChanges = false + modal.dataset.hasChanges = false }) - let fileType + let fileType, documentType, interventionId document.querySelectorAll('.open-modal-upload-files-btn').forEach((button) => { button.addEventListener('click', (e) => { fileType = e.target.dataset.fileType + documentType = e.target.dataset.documentType ?? null + interventionId = e.target.dataset.interventionId ?? null }) }) - modalUploadFiles.addEventListener('dsfr.disclose', (e) => { + modal.addEventListener('dsfr.disclose', (e) => { listContainer.innerHTML = ''; - modalUploadFiles.dataset.validated = false - modalUploadFiles.dataset.hasChanges = false - modalUploadFiles.querySelectorAll('.type-conditional').forEach((type) => { + modal.dataset.validated = false + modal.dataset.hasChanges = false + modal.querySelectorAll('.type-conditional').forEach((type) => { type.classList.add('fr-hidden') }) + modal.dataset.documentType = documentType + modal.dataset.interventionId = interventionId if (fileType == 'photo') { - modalUploadFiles.dataset.fileType = 'photo' - modalUploadFiles.querySelector('.type-photo').classList.remove('fr-hidden') + modal.dataset.fileType = 'photo' + modal.querySelector('.type-photo').classList.remove('fr-hidden') fileSelectorInput.setAttribute('accept', 'image/*') } else { - modalUploadFiles.dataset.fileType = 'document' - modalUploadFiles.querySelector('.type-document').classList.remove('fr-hidden') + modal.dataset.fileType = 'document' + modal.querySelector('.type-document').classList.remove('fr-hidden') fileSelectorInput.setAttribute('accept', '*/*') } + }) btnValidate.addEventListener('click', (e) => { - modalUploadFiles.dataset.validated = true + modal.dataset.validated = true }) - } \ No newline at end of file diff --git a/src/Controller/Back/SignalementFileController.php b/src/Controller/Back/SignalementFileController.php index 4060ee791..744bf396b 100755 --- a/src/Controller/Back/SignalementFileController.php +++ b/src/Controller/Back/SignalementFileController.php @@ -12,6 +12,7 @@ use App\Manager\SuiviManager; use App\Messenger\Message\PdfExportMessage; use App\Repository\FileRepository; +use App\Repository\InterventionRepository; use App\Service\Signalement\SignalementFileProcessor; use App\Service\UploadHandlerService; use Doctrine\ORM\EntityManagerInterface; @@ -214,6 +215,7 @@ public function editFileSignalement( Request $request, FileRepository $fileRepository, EntityManagerInterface $entityManager, + InterventionRepository $interventionRepository, ): Response { if (!$this->isCsrfTokenValid('signalement_edit_file_'.$signalement->getId(), $request->get('_token'))) { if ($request->isXmlHttpRequest()) { @@ -250,6 +252,13 @@ public function editFileSignalement( $file->setDocumentType($documentType); $desordreSlug = $request->get('desordreSlug'); $file->setDesordreSlug($desordreSlug); + $interventionId = $request->get('interventionId'); + if (null !== $interventionId) { + $intervention = $interventionRepository->findOneBy(['id' => $interventionId]); + if ($intervention->getSignalement() === $file->getSignalement()) { + $file->setIntervention($intervention); + } + } $entityManager->persist($file); $entityManager->flush(); if ($request->isXmlHttpRequest()) { diff --git a/src/Security/Voter/InterventionVoter.php b/src/Security/Voter/InterventionVoter.php index 75797ded0..ae448227b 100755 --- a/src/Security/Voter/InterventionVoter.php +++ b/src/Security/Voter/InterventionVoter.php @@ -39,7 +39,10 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ public function canEditVisite(Intervention $intervention, User $user): bool { $signalement = $intervention->getSignalement(); - if (Signalement::STATUS_ACTIVE !== $signalement->getStatut() && Signalement::STATUS_NEED_PARTNER_RESPONSE !== $signalement->getStatut()) { + if ( + Signalement::STATUS_ACTIVE !== $signalement->getStatut() && + Signalement::STATUS_NEED_PARTNER_RESPONSE !== $signalement->getStatut() + ) { return false; } diff --git a/templates/back/signalement/view/photos-documents.html.twig b/templates/back/signalement/view/photos-documents.html.twig index 649498a39..5058e59f9 100755 --- a/templates/back/signalement/view/photos-documents.html.twig +++ b/templates/back/signalement/view/photos-documents.html.twig @@ -139,7 +139,7 @@ {% if doc.intervention is null %} {{ doc.title|truncate_filename(45) }} {% else %} - Rapport de visite du {{ doc.intervention.scheduledAt|date('d/m/Y') }} + Rapport de la visite du {{ doc.intervention.scheduledAt|date('d/m/Y') }} par {{ doc.intervention.partner.nom}} {% endif %}
diff --git a/templates/back/signalement/view/visites/modals/visites-modal-upload-files.html.twig b/templates/back/signalement/view/visites/modals/visites-modal-upload-files.html.twig new file mode 100644 index 000000000..eabac7f7c --- /dev/null +++ b/templates/back/signalement/view/visites/modals/visites-modal-upload-files.html.twig @@ -0,0 +1,73 @@ + +
+
+
+
+
+ +
+
+
+

+ Ajout du rapport de visite +

+
+

Le rapport de visite sera partagé à l'usager.

+
+
+
+

+ Ajout des photos de la visite +

+
+ Ajouter une ou plusieurs photos au signalement. +
+
+

Les photos seront partagées à l'usager.

+
+
+ + +
+ +
+
+
+
+
\ No newline at end of file diff --git a/templates/back/signalement/view/visites/modals/visites-modals.html.twig b/templates/back/signalement/view/visites/modals/visites-modals.html.twig index 7b2a5ab4c..6562b5b99 100755 --- a/templates/back/signalement/view/visites/modals/visites-modals.html.twig +++ b/templates/back/signalement/view/visites/modals/visites-modals.html.twig @@ -9,5 +9,8 @@ {% include 'back/signalement/view/visites/modals/visites-modal-reschedule.html.twig' %} {% elseif intervention.status is same as constant('App\\Entity\\Intervention::STATUS_DONE') %} {% include 'back/signalement/view/visites/modals/visites-modal-edit.html.twig' %} + {% if (is_granted('FILE_CREATE', signalement) and isDocumentsEnabled) %} + {% include 'back/signalement/view/visites/modals/visites-modal-upload-files.html.twig' %} + {% endif %} {% endif %} {% endif %} \ No newline at end of file diff --git a/templates/back/signalement/view/visites/visite-item.html.twig b/templates/back/signalement/view/visites/visite-item.html.twig index 2662a36a5..af359139c 100755 --- a/templates/back/signalement/view/visites/visite-item.html.twig +++ b/templates/back/signalement/view/visites/visite-item.html.twig @@ -60,20 +60,6 @@ {% endif %} {% endif %} -
- Rapport : - {% if signalement.interventions is empty or intervention.files is empty %} - Non disponible - {% else %} - - Voir le rapport de visite - - {% endif %} -
Commentaire du partenaire : diff --git a/templates/back/signalement/view/visites/visites-buttons.html.twig b/templates/back/signalement/view/visites/visites-buttons.html.twig index 21b2e6e55..8aefb22d1 100755 --- a/templates/back/signalement/view/visites/visites-buttons.html.twig +++ b/templates/back/signalement/view/visites/visites-buttons.html.twig @@ -1,26 +1,65 @@
- {% if signalement.interventions is empty %} + {% if signalement.interventions is empty %} - {% elseif intervention.status is same as constant('App\\Entity\\Intervention::STATUS_PLANNED') %} - {% if workflow_can(intervention, 'cancel') %} - + {% endif %} + + {% if workflow_can(intervention, 'confirm') %} + + {% endif %} {% endif %} - - {% if workflow_can(intervention, 'confirm') %} - + {% endif %} + {% else %} + {% if is_granted('INTERVENTION_EDIT_VISITE', intervention) %} + + {% endif %} + + Voir le rapport de visite + + {% endif %} + {% if isDocumentsEnabled and is_granted('INTERVENTION_EDIT_VISITE', intervention)%} + {% endif %} - {% elseif intervention.status is same as constant('App\\Entity\\Intervention::STATUS_DONE') %} - {% else %}   {% endif %} diff --git a/templates/back/signalement/view/visites/visites-list.html.twig b/templates/back/signalement/view/visites/visites-list.html.twig index c1f9fd602..2d6533df8 100755 --- a/templates/back/signalement/view/visites/visites-list.html.twig +++ b/templates/back/signalement/view/visites/visites-list.html.twig @@ -24,8 +24,8 @@
{% if is_granted('INTERVENTION_EDIT_VISITE', intervention) %} {% include 'back/signalement/view/visites/modals/visites-modals.html.twig' %} - {% include 'back/signalement/view/visites/visites-buttons.html.twig' %} {% endif %} + {% include 'back/signalement/view/visites/visites-buttons.html.twig' %}
{% include 'back/signalement/view/visites/visite-item.html.twig' %} From da87b789c62aeb654ecef48686e60e2b6b481439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9l=C3=A8ne=20Meneuvrier?= Date: Tue, 12 Mar 2024 21:20:01 +0100 Subject: [PATCH 02/11] wip suivi and miniature #2198 --- src/Manager/SuiviManager.php | 24 ++++++++- .../signalement/view/photos-album.html.twig | 16 ++++-- .../view/visites/visite-item.html.twig | 51 +++++++++++++++++++ 3 files changed, 86 insertions(+), 5 deletions(-) diff --git a/src/Manager/SuiviManager.php b/src/Manager/SuiviManager.php index 7a79fc8ef..86fc685dc 100644 --- a/src/Manager/SuiviManager.php +++ b/src/Manager/SuiviManager.php @@ -2,6 +2,7 @@ namespace App\Manager; +use App\Entity\Enum\DocumentType; use App\Entity\File; use App\Entity\Signalement; use App\Entity\Suivi; @@ -72,6 +73,8 @@ public function addSuiviIfNeeded( public function createInstanceForFilesSignalement(User $user, Signalement $signalement, array $files): Suivi { + $isRapportDeVisite = false; + $isPhotoDeVisite = false; $nbDocs = 0; $nbPhotos = 0; foreach ($files as $file) { @@ -80,11 +83,22 @@ public function createInstanceForFilesSignalement(User $user, Signalement $signa } else { ++$nbDocs; } + + if (DocumentType::PROCEDURE_RAPPORT_DE_VISITE === $file->getDocumentType()) { + $isRapportDeVisite = true; + } + if (DocumentType::PHOTO_VISITE === $file->getDocumentType()) { + $isPhotoDeVisite = true; + } } $description = ''; if ($nbDocs > 0) { $description .= $nbDocs; - $description .= $nbDocs > 1 ? ' documents partenaires' : ' document partenaire'; + if ($isRapportDeVisite) { + $description .= $nbDocs > 1 ? ' rapports de visite' : ' rapport de visite'; + } else { + $description .= $nbDocs > 1 ? ' documents partenaires' : ' document partenaire'; + } } if ($nbPhotos > 0) { if ('' !== $description) { @@ -92,6 +106,9 @@ public function createInstanceForFilesSignalement(User $user, Signalement $signa } $description .= $nbPhotos; $description .= $nbPhotos > 1 ? ' photos' : ' photo'; + if ($isPhotoDeVisite) { + $description .= ' de visite'; + } } if ($nbDocs + $nbPhotos > 1) { $description .= ' ont été ajoutés au signalement : '; @@ -111,6 +128,11 @@ public function createInstanceForFilesSignalement(User $user, Signalement $signa .implode('', $descriptionList) .'' ); + + if ($isRapportDeVisite || $isPhotoDeVisite) { + $suivi->setIsPublic(true); + } + $suivi->setType(SUIVI::TYPE_AUTO); return $suivi; diff --git a/templates/back/signalement/view/photos-album.html.twig b/templates/back/signalement/view/photos-album.html.twig index d501fe7f2..35a3c01cc 100755 --- a/templates/back/signalement/view/photos-album.html.twig +++ b/templates/back/signalement/view/photos-album.html.twig @@ -3,16 +3,19 @@
- {% set loopLength = signalement.files|filter( photo => photo.fileType == 'photo' and photo.intervention is null )|length %} + {# {% set loopLength = signalement.files|filter( photo => photo.fileType == 'photo' and photo.intervention is null )|length %} #} + {% set loopLength = signalement.files|filter( photo => photo.fileType == 'photo' )|length %}
- {% for index, photo in signalement.files|filter( photo => photo.fileType == 'photo' and photo.intervention is null ) %} + {# {% for index, photo in signalement.files|filter( photo => photo.fileType == 'photo' and photo.intervention is null ) %} #} + {% for index, photo in signalement.files|filter( photo => photo.fileType == 'photo' ) %}
- Photo de la situation - {{ loop.index }} / {{ loopLength }} + {# Photo de la situation - {{ loop.index }} / {{ loopLength }} #} + {{ photo.documentType.label}} - {{ loop.index }} / {{ loopLength }}
{% endif %} + {% if photo.description is not same as null %} + {{ photo.description }} + {% endif %} +
Photo ajoutée par {{ photo.uploadedBy.nomComplet ?? 'l\'usager' }}
@@ -42,7 +49,8 @@
diff --git a/templates/back/signalement/view/visites/visite-item.html.twig b/templates/back/signalement/view/visites/visite-item.html.twig index af359139c..9aebd5188 100755 --- a/templates/back/signalement/view/visites/visite-item.html.twig +++ b/templates/back/signalement/view/visites/visite-item.html.twig @@ -74,3 +74,54 @@
+ +
+ {% for index, photo in signalement.files|filter( + photo => photo.fileType == 'photo' + and photo.intervention is not null + and photo.intervention.id is same as intervention.id + ) %} +
+
+ + {% if is_granted('FILE_EDIT', photo) %} + {% set DocumentType = enum('\\App\\Entity\\Enum\\DocumentType') %} + {% include 'back/signalement/view/edit-modals/edit-file.html.twig' %} + + {% endif %} + {# {% if is_granted('FILE_DELETE', photo) %} + + {% endif %} #} +
+
+ {% endfor %} +
From 8c2bb609bf3a8f7db8354e5cc24e74878c1b74c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9l=C3=A8ne=20Meneuvrier?= Date: Mon, 18 Mar 2024 12:48:40 +0100 Subject: [PATCH 03/11] sort photos and add description #2198 --- .../form_upload_documents.js | 73 +++++++++++++------ src/Controller/Back/SignalementController.php | 3 + .../Back/SignalementFileController.php | 4 + src/Manager/SignalementManager.php | 49 +++++++++++++ .../signalement/view/photos-album.html.twig | 15 ++-- 5 files changed, 112 insertions(+), 32 deletions(-) diff --git a/assets/controllers/back_signalement_view/form_upload_documents.js b/assets/controllers/back_signalement_view/form_upload_documents.js index a81b5cada..fb010143b 100644 --- a/assets/controllers/back_signalement_view/form_upload_documents.js +++ b/assets/controllers/back_signalement_view/form_upload_documents.js @@ -157,25 +157,10 @@ function initializeUploadModal( } } else { if (null !== modal.dataset.documentType){ - let httpEdit = new XMLHttpRequest() - let dataEdit = new FormData() - dataEdit.append('file_id', response.response) - dataEdit.append('documentType', modal.dataset.documentType) - dataEdit.append('interventionId', modal.dataset.interventionId) - - dataEdit.append('_token', editFileToken) - httpEdit.onreadystatechange = function () { - if (this.readyState == XMLHttpRequest.DONE) { - let response = JSON.parse(this.response) - if (this.status != 200) { - let parent = fileListContainerSelector - parent.querySelector('.file-error').innerHTML = '
' + response.response + '
' - } - } - } - httpEdit.open('POST', editFileRoute, true) - httpEdit.setRequestHeader("X-Requested-With", "XMLHttpRequest") - httpEdit.send(dataEdit) + let divFileId = div.querySelector('#file-id') + divFileId.value = response.response + callEditFileRoute(div) + addEventListenerDescription(div) } } @@ -215,9 +200,20 @@ function initializeUploadModal( 0% -
-
-
+ ` + if (modal.dataset.documentType == 'PHOTO_VISITE') { + innerHTML += ` +
+ + +
+ ` + } else{ + innerHTML += `
+
` + } + innerHTML += `
` @@ -272,6 +268,38 @@ function initializeUploadModal( }) } + function callEditFileRoute(divFileItem) { + let httpEdit = new XMLHttpRequest() + let dataEdit = new FormData() + dataEdit.append('file_id', divFileItem.querySelector('#file-id')?.value) + dataEdit.append('documentType', modal.dataset.documentType) + dataEdit.append('interventionId', modal.dataset.interventionId) + dataEdit.append('description', divFileItem.querySelector('#file-description')?.value) + + dataEdit.append('_token', editFileToken) + httpEdit.onreadystatechange = function () { + if (this.readyState == XMLHttpRequest.DONE) { + let response = JSON.parse(this.response) + if (this.status != 200) { + let parent = divFileItem + parent.querySelector('.file-error').innerHTML = '
' + response.response + '
' + + } + } + } + httpEdit.open('POST', editFileRoute, true) + httpEdit.setRequestHeader("X-Requested-With", "XMLHttpRequest") + httpEdit.send(dataEdit) + } + + function addEventListenerDescription(divFileItem) { + listContainer?.querySelectorAll('.fr-grid-row')?.forEach(divFileItem => { + divFileItem.querySelector('#file-description')?.addEventListener('change', (e) => { + callEditFileRoute(divFileItem) + }) + }) + } + modal.addEventListener('dsfr.conceal', (e) => { if (modal.dataset.validated == "true" && modal.dataset.hasChanges == "true") { @@ -319,5 +347,4 @@ function initializeUploadModal( btnValidate.addEventListener('click', (e) => { modal.dataset.validated = true }) - } \ No newline at end of file diff --git a/src/Controller/Back/SignalementController.php b/src/Controller/Back/SignalementController.php index b1e758bf1..8ba3bbd71 100755 --- a/src/Controller/Back/SignalementController.php +++ b/src/Controller/Back/SignalementController.php @@ -178,6 +178,8 @@ public function viewSignalement( $partnerVisite = $affectationRepository->findAffectationWithQualification(Qualification::VISITES, $signalement); + $allPhotosOrdered = $signalementManager->getAllPhotosOrdered($signalement); + return $this->render('back/signalement/view.html.twig', [ 'title' => 'Signalement', 'createdFromDraft' => $signalement->getCreatedFrom(), @@ -206,6 +208,7 @@ public function viewSignalement( 'partnersCanVisite' => $partnerVisite, 'pendingVisites' => $interventionRepository->getPendingVisitesForSignalement($signalement), 'isDocumentsEnabled' => $parameterBag->get('feature_documents_enable'), + 'allPhotosOrdered' => $allPhotosOrdered, ]); } diff --git a/src/Controller/Back/SignalementFileController.php b/src/Controller/Back/SignalementFileController.php index 744bf396b..65f04d482 100755 --- a/src/Controller/Back/SignalementFileController.php +++ b/src/Controller/Back/SignalementFileController.php @@ -259,6 +259,10 @@ public function editFileSignalement( $file->setIntervention($intervention); } } + $description = $request->get('description'); + if (null !== $description) { + $file->setDescription($description); + } $entityManager->persist($file); $entityManager->flush(); if ($request->isXmlHttpRequest()) { diff --git a/src/Manager/SignalementManager.php b/src/Manager/SignalementManager.php index a96d70b4d..5b3d8223d 100644 --- a/src/Manager/SignalementManager.php +++ b/src/Manager/SignalementManager.php @@ -814,6 +814,55 @@ public function getPhotosBySlug(Signalement $signalement, string $desordrePrecis return $photos->toArray(); } + public function getAllPhotosOrdered(Signalement $signalement): ?array + { + $photos = $signalement->getPhotos(); + $photosArray = $photos->toArray(); + $photoArraysByType = [ + DocumentType::PHOTO_SITUATION->value => [], + DocumentType::PHOTO_VISITE->value => [], + DocumentType::AUTRE->value => [], + ]; + + foreach ($photosArray as $photo) { + $type = $photo->getDocumentType(); + $photoArraysByType[$type->value][] = $photo; + } + + foreach ($photoArraysByType as &$photoArray) { + usort($photoArray, function (File $a, File $b) { + if (DocumentType::PHOTO_SITUATION === $a->getDocumentType()) { + return $a->getId() <=> $b->getId(); + } + if (DocumentType::PHOTO_VISITE === $a->getDocumentType()) { + $interventionA = $a->getIntervention(); + $interventionB = $b->getIntervention(); + if (null === $interventionA && null === $interventionB) { + return 0; + } + if (null === $interventionA) { + return 1; + } + if (null === $interventionB) { + return -1; + } + + return $interventionA->getId() <=> $interventionB->getId(); + } + + return $a->getId() <=> $b->getId(); + }); + } + + $sortedPhotos = array_merge( + $photoArraysByType[DocumentType::PHOTO_SITUATION->value], + $photoArraysByType[DocumentType::AUTRE->value], + $photoArraysByType[DocumentType::PHOTO_VISITE->value] + ); + + return $sortedPhotos; + } + /** * @todo: Investigate Twig\Error\RuntimeError in ajax request * Hack: generate csrf token in side server for ajav request diff --git a/templates/back/signalement/view/photos-album.html.twig b/templates/back/signalement/view/photos-album.html.twig index 35a3c01cc..25b626ab2 100755 --- a/templates/back/signalement/view/photos-album.html.twig +++ b/templates/back/signalement/view/photos-album.html.twig @@ -2,19 +2,15 @@
- - {# {% set loopLength = signalement.files|filter( photo => photo.fileType == 'photo' and photo.intervention is null )|length %} #} - {% set loopLength = signalement.files|filter( photo => photo.fileType == 'photo' )|length %} + {% set loopLength = allPhotosOrdered|length %}
- {# {% for index, photo in signalement.files|filter( photo => photo.fileType == 'photo' and photo.intervention is null ) %} #} - {% for index, photo in signalement.files|filter( photo => photo.fileType == 'photo' ) %} + {% for index, photo in allPhotosOrdered %}
- {# Photo de la situation - {{ loop.index }} / {{ loopLength }} #} {{ photo.documentType.label}} - {{ loop.index }} / {{ loopLength }}
@@ -29,6 +25,8 @@ {% if photo.documentType is same as enum('App\\Entity\\Enum\\DocumentType').PHOTO_SITUATION and photo.desordreSlug is not same as null %} {{ signalement.getDesordreLabel(photo.desordreSlug) }} + {% elseif photo.documentType is same as enum('App\\Entity\\Enum\\DocumentType').PHOTO_VISITE %} + {{ photo.documentType.label() }} du {{ photo.intervention.scheduledAt|date('d/m/Y') }} par {{ photo.intervention.partner.nom}} {% else %} {{ photo.documentType.label() }} {% endif %} @@ -49,9 +47,8 @@
From 0a8eb36425e7fe02697048956766a6dc0fe03dfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9l=C3=A8ne=20Meneuvrier?= Date: Mon, 18 Mar 2024 15:51:05 +0100 Subject: [PATCH 04/11] edit photo description #2198 --- .../back_signalement_edit_file.js | 10 +++++++++- .../signalement/view/edit-modals/edit-file.html.twig | 7 ++++++- .../back/signalement/view/photos-documents.html.twig | 1 + .../signalement/view/visites/visite-item.html.twig | 1 + 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/assets/controllers/back_signalement_edit_file/back_signalement_edit_file.js b/assets/controllers/back_signalement_edit_file/back_signalement_edit_file.js index e293a484f..c41ae01f8 100644 --- a/assets/controllers/back_signalement_edit_file/back_signalement_edit_file.js +++ b/assets/controllers/back_signalement_edit_file/back_signalement_edit_file.js @@ -60,8 +60,16 @@ document.querySelectorAll('.btn-signalement-file-edit').forEach(swbtn => { + ' par '+ target.getAttribute('data-partner-name')+target.getAttribute('data-user-name') document.querySelector('#file-edit-fileid').value = target.getAttribute('data-file-id') + const selectedDocumentType = target.getAttribute('data-documentType'); + if (target.getAttribute('data-description') || selectedDocumentType === 'PHOTO_VISITE') { + document.querySelector('#fileDescription').value = target.getAttribute('data-description') + document.querySelector('#fr-modal-edit-file-description').classList.remove('fr-hidden') + }else { + document.querySelector('#fileDescription').value = '' + document.querySelector('#fr-modal-edit-file-description').classList.add('fr-hidden') + } + const documentTypes = JSON.parse(target.getAttribute('data-documentType-list')); - const selectedDocumentType = target.getAttribute('data-documentType'); let typeSelectBox = document.querySelector('#document-type-select'); typeSelectBox.innerHTML = ''; let option = new Option('Sélectionnez un type', ''); diff --git a/templates/back/signalement/view/edit-modals/edit-file.html.twig b/templates/back/signalement/view/edit-modals/edit-file.html.twig index 817453102..a2c31a21d 100755 --- a/templates/back/signalement/view/edit-modals/edit-file.html.twig +++ b/templates/back/signalement/view/edit-modals/edit-file.html.twig @@ -18,9 +18,14 @@
-
+
+
+ + +
+
diff --git a/templates/back/signalement/view/photos-documents.html.twig b/templates/back/signalement/view/photos-documents.html.twig index 5058e59f9..cf5721e3d 100755 --- a/templates/back/signalement/view/photos-documents.html.twig +++ b/templates/back/signalement/view/photos-documents.html.twig @@ -93,6 +93,7 @@ data-type="photo" data-file-id="{{ photo.id}}" data-signalement-uuid="{{ signalement.uuid}}" + data-description="{{ photo.description }}" data-documentType="{{ photo.documentType.name }}" data-documentType-list="{{ DocumentType.getPhotosList() | json_encode }}" data-createdAt="{{ photo.createdAt is defined ? photo.createdAt|date('d.m.Y') : 'N/R' }}" diff --git a/templates/back/signalement/view/visites/visite-item.html.twig b/templates/back/signalement/view/visites/visite-item.html.twig index 9aebd5188..6e3d7959f 100755 --- a/templates/back/signalement/view/visites/visite-item.html.twig +++ b/templates/back/signalement/view/visites/visite-item.html.twig @@ -104,6 +104,7 @@ data-type="photo" data-file-id="{{ photo.id}}" data-signalement-uuid="{{ signalement.uuid}}" + data-description="{{ photo.description }}" data-documentType="{{ photo.documentType.name }}" data-documentType-list="{{ DocumentType.getPhotosList() | json_encode }}" data-createdAt="{{ photo.createdAt is defined ? photo.createdAt|date('d.m.Y') : 'N/R' }}" From 376607c6369639d4f98bfe007585ff7aea8c2bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9l=C3=A8ne=20Meneuvrier?= Date: Tue, 19 Mar 2024 16:02:37 +0100 Subject: [PATCH 05/11] select document between procedure and situation #2198 --- .../form_upload_documents.js | 62 +++--- src/Entity/Enum/DocumentType.php | 15 +- .../_partials/_modal_upload_files.html.twig | 39 ++-- templates/back/signalement/view.html.twig | 29 +-- .../view/photos-documents.html.twig | 185 +++++++++--------- 5 files changed, 173 insertions(+), 157 deletions(-) diff --git a/assets/controllers/back_signalement_view/form_upload_documents.js b/assets/controllers/back_signalement_view/form_upload_documents.js index fb010143b..51f01dd10 100644 --- a/assets/controllers/back_signalement_view/form_upload_documents.js +++ b/assets/controllers/back_signalement_view/form_upload_documents.js @@ -1,58 +1,44 @@ initializeUploadModal( '#fr-modal-upload-files', - '.modal-upload-drop-section', - '.modal-upload-list', - '.modal-upload-files-selector', - '.modal-upload-files-selector-input', - '#select-type-to-clone', + '#select-type-situation-to-clone', + '#select-type-procedure-to-clone', '#select-desordre-to-clone', - '#btn-validate-modal-upload-files', - '#modal-upload-file-dynamic-content' ); document?.querySelectorAll('.fr-modal-visites-upload-files')?.forEach(modalVisiteUpload => { initializeUploadModal( '#'+modalVisiteUpload.id, - '.modal-upload-drop-section', - '.modal-upload-list', - '.modal-upload-files-selector', - '.modal-upload-files-selector-input', null, null, - '#btn-validate-modal-upload-files', - '#modal-upload-file-dynamic-content' + null, ) }) function initializeUploadModal( modalSelector, - fileDropAreaSelector, - fileListContainerSelector, - fileTypeSelector, - fileInputSelector, - selectTypeToCloneSelector, + selectTypeSituationToCloneSelector, + selectTypeProcedureToCloneSelector, selectDesordreToCloneSelector, - btnValidateSelector, - ancreSelector ) { const modal = document?.querySelector(modalSelector); if (!modal) return; - const dropArea = modal.querySelector(fileDropAreaSelector); - const listContainer = modal.querySelector(fileListContainerSelector); - const fileSelector = modal.querySelector(fileTypeSelector) - const fileSelectorInput = modal.querySelector(fileInputSelector) + const dropArea = modal.querySelector('.modal-upload-drop-section'); + const listContainer = modal.querySelector('.modal-upload-list'); + const fileSelector = modal.querySelector('.modal-upload-files-selector') + const fileSelectorInput = modal.querySelector('.modal-upload-files-selector-input') const addFileRoute = modal.dataset.addFileRoute; const addFileToken = modal.dataset.addFileToken; const waitingSuiviRoute = modal.dataset.waitingSuiviRoute; const deleteTmpFileRoute = modal.dataset.deleteTmpFileRoute; - const selectTypeToClone = selectTypeToCloneSelector ? modal.querySelector(selectTypeToCloneSelector) : null; + const selectTypeSituationToClone = selectTypeSituationToCloneSelector ? modal.querySelector(selectTypeSituationToCloneSelector) : null; + const selectTypeProcedureToClone = selectTypeProcedureToCloneSelector ? modal.querySelector(selectTypeProcedureToCloneSelector) : null; const selectDesordreToClone = selectDesordreToCloneSelector ? modal.querySelector(selectDesordreToCloneSelector) : null; const editFileRoute = modal.dataset.editFileRoute; const editFileToken = modal.dataset.editFileToken; - const btnValidate = modal.querySelector(btnValidateSelector); - const ancre = modal.querySelector(ancreSelector); + const btnValidate = modal.querySelector('#btn-validate-modal-upload-files'); + const ancre = modal.querySelector('#modal-upload-file-dynamic-content'); fileSelector.onclick = () => fileSelectorInput.click() @@ -139,13 +125,16 @@ function initializeUploadModal( addEventListenerDeleteTmpFile(btnDeleteTmpFile) if (this.status == 200) { modal.dataset.hasChanges = true - if (null !== selectDesordreToClone || null !== selectTypeToClone){ + if (null !== selectDesordreToClone || null !== selectTypeSituationToClone || null !== selectTypeProcedureToClone){ let clone if (modal.dataset.fileType == 'photo') { clone = selectDesordreToClone.cloneNode(true) clone.id = 'select-desordre-' + response.response - } else { - clone = selectTypeToClone.cloneNode(true) + if ('situation' === modal.dataset.fileFilter ){ + clone = selectTypeSituationToClone.cloneNode(true) + } else { + clone = selectTypeProcedureToClone.cloneNode(true) + } clone.id = 'select-type-' + response.response } clone.dataset.fileId = response.response @@ -314,10 +303,11 @@ function initializeUploadModal( modal.dataset.hasChanges = false }) - let fileType, documentType, interventionId + let fileType, fileFilter, documentType, interventionId document.querySelectorAll('.open-modal-upload-files-btn').forEach((button) => { button.addEventListener('click', (e) => { fileType = e.target.dataset.fileType + fileFilter = e.target.dataset.fileFilter documentType = e.target.dataset.documentType ?? null interventionId = e.target.dataset.interventionId ?? null }) @@ -330,7 +320,11 @@ function initializeUploadModal( modal.querySelectorAll('.type-conditional').forEach((type) => { type.classList.add('fr-hidden') }) + modal.querySelectorAll('.filter-conditional').forEach((type) => { + type.classList.add('fr-hidden') + }) modal.dataset.documentType = documentType + modal.dataset.fileFilter = fileFilter modal.dataset.interventionId = interventionId if (fileType == 'photo') { modal.dataset.fileType = 'photo' @@ -340,8 +334,12 @@ function initializeUploadModal( modal.dataset.fileType = 'document' modal.querySelector('.type-document').classList.remove('fr-hidden') fileSelectorInput.setAttribute('accept', '*/*') + } + if (fileFilter == 'procedure') { + modal.querySelector('.filter-procedure').classList.remove('fr-hidden') + } else if (fileFilter == 'situation') { + modal.querySelector('.filter-situation').classList.remove('fr-hidden') } - }) btnValidate.addEventListener('click', (e) => { diff --git a/src/Entity/Enum/DocumentType.php b/src/Entity/Enum/DocumentType.php index 44ba600f3..008f59891 100644 --- a/src/Entity/Enum/DocumentType.php +++ b/src/Entity/Enum/DocumentType.php @@ -47,18 +47,26 @@ public static function getPhotosList(): array { return [ self::PHOTO_SITUATION->name => self::PHOTO_SITUATION->label(), - self::PHOTO_VISITE->name => self::PHOTO_VISITE->label(), + self::PHOTO_VISITE->name => self::PHOTO_VISITE->label(), // TODO, garder ? self::AUTRE->name => self::AUTRE->label(), ]; } - public static function getDocumentsList(): array + public static function getSituationList(): array { return [ + self::PHOTO_SITUATION->name => self::PHOTO_SITUATION->label(), + self::AUTRE->name => self::AUTRE->label(), self::SITUATION_FOYER_BAIL->name => self::SITUATION_FOYER_BAIL->label(), self::SITUATION_FOYER_DPE->name => self::SITUATION_FOYER_DPE->label(), self::SITUATION_FOYER_ETAT_DES_LIEUX->name => self::SITUATION_FOYER_ETAT_DES_LIEUX->label(), self::SITUATION_DIAGNOSTIC_PLOMB_AMIANTE->name => self::SITUATION_DIAGNOSTIC_PLOMB_AMIANTE->label(), + ]; + } + + public static function getProcedureList(): array + { + return [ self::PROCEDURE_MISE_EN_DEMEURE->name => self::PROCEDURE_MISE_EN_DEMEURE->label(), self::PROCEDURE_RAPPORT_DE_VISITE->name => self::PROCEDURE_RAPPORT_DE_VISITE->label(), self::PROCEDURE_ARRETE_MUNICIPAL->name => self::PROCEDURE_ARRETE_MUNICIPAL->label(), @@ -66,9 +74,6 @@ public static function getDocumentsList(): array self::PROCEDURE_SAISINE->name => self::PROCEDURE_SAISINE->label(), self::BAILLEUR_DEVIS_POUR_TRAVAUX->name => self::BAILLEUR_DEVIS_POUR_TRAVAUX->label(), self::BAILLEUR_REPONSE_BAILLEUR->name => self::BAILLEUR_REPONSE_BAILLEUR->label(), - self::PHOTO_SITUATION->name => self::PHOTO_SITUATION->label(), - self::PHOTO_VISITE->name => self::PHOTO_VISITE->label(), - self::AUTRE->name => self::AUTRE->label(), ]; } } diff --git a/templates/_partials/_modal_upload_files.html.twig b/templates/_partials/_modal_upload_files.html.twig index a693df3e8..70d56b6f2 100644 --- a/templates/_partials/_modal_upload_files.html.twig +++ b/templates/_partials/_modal_upload_files.html.twig @@ -22,17 +22,28 @@
-

- Ajouter des documents partenaires -

-
- Ajouter un ou plusieurs documents. Pour chaque document, veuillez renseigner son type. +
+

+ Ajouter des documents liés à la procédure +

+
+ Ajouter un ou plusieurs documents. Pour chaque document, veuillez renseigner son type. +
+
+

Pour ajouter des documents de type Bail, DPE, Diagnostic et Etat des lieux, rendez-vous dans la partie "Déclaration usager".

+
- {# -
-

Pour ajouter des documents de type Bail, DPE, Diagnostic et Etat des lieux, rendez-vous dans la partie "Déclaration usager".

+
+

+ Ajouter des documents liés à la situation +

+
+ Ajouter un ou plusieurs documents. Pour chaque document, veuillez renseigner son type. +
+
+

Ces photos seront partagées à l'usager.

+
- #}

@@ -61,9 +72,15 @@

{% set DocumentType = enum('\\App\\Entity\\Enum\\DocumentType') %} - + + {% for key, value in DocumentType.getSituationList() %} + + {% endfor %} + + diff --git a/templates/back/signalement/view.html.twig b/templates/back/signalement/view.html.twig index 2cfbf59d3..f01f6c143 100755 --- a/templates/back/signalement/view.html.twig +++ b/templates/back/signalement/view.html.twig @@ -41,36 +41,25 @@ {% include 'back/signalement/view/user-declaration.html.twig' %} - {% if createdFromDraft %} - {% include 'back/signalement/view/photos-documents.html.twig' with { - 'zonetitle': "Photos et documents de la situation", - 'importedBy': "user" - } %} - {% endif %} + {% include 'back/signalement/view/photos-documents.html.twig' with { + 'zonetitle': "Photos et documents de la situation", + 'filesFilter': 'situation' + } %} {% include 'back/signalement/view/information.html.twig' %} {% include 'back/signalement/view/nde.html.twig' %} - - {% if not createdFromDraft %} - {% include 'back/signalement/view/photos-documents.html.twig' with { - 'zonetitle': "Photos et documents", - 'importedBy': "all" - } %} - {% endif %} - + {% include 'back/signalement/view/partners.html.twig' %} {% include 'back/signalement/view/suivis.html.twig' %} {% include 'back/signalement/view/visites/visites-list.html.twig' %} - {% if createdFromDraft %} - {% include 'back/signalement/view/photos-documents.html.twig' with { - 'zonetitle': "Photos et documents liés à la procédure", - 'importedBy': "partner" - } %} - {% endif %} + {% include 'back/signalement/view/photos-documents.html.twig' with { + 'zonetitle': "Documents liés à la procédure", + 'filesFilter': 'procedure' + } %} {% endblock %} {% block javascripts %} diff --git a/templates/back/signalement/view/photos-documents.html.twig b/templates/back/signalement/view/photos-documents.html.twig index cf5721e3d..57f4e2d31 100755 --- a/templates/back/signalement/view/photos-documents.html.twig +++ b/templates/back/signalement/view/photos-documents.html.twig @@ -1,35 +1,41 @@ -{% if importedBy is not same as 'user' %} -
+
-
-
-

{{ zonetitle }}

-
-
- {% if (is_granted('FILE_CREATE', signalement)) %} - {% if isDocumentsEnabled %} - +
+
+

{{ zonetitle }}

+
+
+ {% if (is_granted('FILE_CREATE', signalement)) %} + {% if isDocumentsEnabled %} + + {% if filesFilter is same as 'situation' %} - {% else %} -
- - - -
+ {% endif %} + {% else %} +
+ + + +
+ {% if filesFilter is same as 'situation' %}
+ + + {% endif %}
+
+{% if filesFilter is same as 'situation' %}

Pour ajouter plusieurs photos ou documents à la fois, sélectionnez vos fichiers en maintenant la touche CTRL enfoncée.

- -{% else %} -

{{ zonetitle }}

{% endif %} {% if signalement.files|length == 0 %} @@ -60,69 +65,71 @@

{% endif %} -
- {% for index, photo in signalement.files|filter( - photo => photo.fileType == 'photo' - and photo.intervention is null - and ( - (importedBy is same as 'user' and (photo.uploadedBy is null or photo.isUsagerFile )) - or (importedBy is same as 'partner' and (photo.uploadedBy is not null and photo.isPartnerFile)) - or importedBy is same as 'all' - ) - ) %} -
-
- - {% if is_granted('FILE_EDIT', photo) %} - {% set DocumentType = enum('\\App\\Entity\\Enum\\DocumentType') %} - {% include 'back/signalement/view/edit-modals/edit-file.html.twig' %} - - {% endif %} - {% if is_granted('FILE_DELETE', photo) %} + +{% set DocumentType = enum('\\App\\Entity\\Enum\\DocumentType') %} +{% if filesFilter is same as 'situation' %} +
+ {% for index, photo in signalement.files|filter( + photo => photo.fileType == 'photo' + and photo.intervention is null + and filesFilter is same as 'situation' + and photo.documentType.label() in DocumentType.getSituationList + ) %} +
+
- {% endif %} + {% if is_granted('FILE_EDIT', photo) %} + {% include 'back/signalement/view/edit-modals/edit-file.html.twig' %} + + {% endif %} + {% if is_granted('FILE_DELETE', photo) %} + + {% endif %} +
-
- {% endfor %} -
+ {% endfor %} +
+{% endif %} {% for index, doc in signalement.files|filter( doc => doc.fileType == 'document' - and ( - (importedBy is same as 'user' and (doc.uploadedBy is null or doc.isUsagerFile )) - or (importedBy is same as 'partner' and (doc.uploadedBy is not null and doc.isPartnerFile)) - or importedBy is same as 'all' - ) + and ( + (filesFilter is same as 'situation' + and doc.documentType.label() in DocumentType.getSituationList) + or + (filesFilter is same as 'procedure' + and doc.documentType.label() in DocumentType.getProcedureList) + ) ) %}
@@ -161,7 +168,7 @@ data-type="document" data-file-id="{{ doc.id}}" data-documentType="{{ doc.documentType.name }}" - data-documentType-list="{{ DocumentType.getDocumentsList() | json_encode }}" + data-documentType-list="{{ filesFilter is same as 'situation' ? DocumentType.getSituationList() | json_encode : DocumentType.getProcedureList() | json_encode }}" data-createdAt="{{ doc.createdAt is defined ? doc.createdAt|date('d.m.Y') : 'N/R' }}" data-partner-name="{{ doc.uploadedBy and doc.uploadedBy.partner ? doc.uploadedBy.partner.nom ~ ' - ' : '' }}" data-user-name="{{ doc.uploadedBy.nomComplet ?? 'N/R' }}" From f721e3faaeda44812fc4f9b6545a11712c82ef9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9l=C3=A8ne=20Meneuvrier?= Date: Thu, 21 Mar 2024 21:26:18 +0100 Subject: [PATCH 06/11] suivis #2198 --- .../form_upload_documents.js | 8 +- .../Back/SignalementFileController.php | 7 +- src/Entity/Intervention.php | 11 ++ src/Manager/SuiviManager.php | 106 +++++++++++++----- .../view/visites/visites-buttons.html.twig | 5 +- tests/Functional/Manager/SuiviManagerTest.php | 5 + 6 files changed, 106 insertions(+), 36 deletions(-) diff --git a/assets/controllers/back_signalement_view/form_upload_documents.js b/assets/controllers/back_signalement_view/form_upload_documents.js index 51f01dd10..e28aa09eb 100644 --- a/assets/controllers/back_signalement_view/form_upload_documents.js +++ b/assets/controllers/back_signalement_view/form_upload_documents.js @@ -130,6 +130,10 @@ function initializeUploadModal( if (modal.dataset.fileType == 'photo') { clone = selectDesordreToClone.cloneNode(true) clone.id = 'select-desordre-' + response.response + }else{ + console.log(modal.dataset.fileFilter) + console.log(selectTypeSituationToClone) + console.log(selectTypeProcedureToClone) if ('situation' === modal.dataset.fileFilter ){ clone = selectTypeSituationToClone.cloneNode(true) } else { @@ -138,6 +142,7 @@ function initializeUploadModal( clone.id = 'select-type-' + response.response } clone.dataset.fileId = response.response + console.log(clone) if (clone.querySelectorAll('option').length == 1) { clone.remove() } else { @@ -200,7 +205,8 @@ function initializeUploadModal( ` } else{ innerHTML += `
-
` +
+ ` } innerHTML += `
diff --git a/src/Controller/Back/SignalementFileController.php b/src/Controller/Back/SignalementFileController.php index 65f04d482..4d61faefe 100755 --- a/src/Controller/Back/SignalementFileController.php +++ b/src/Controller/Back/SignalementFileController.php @@ -167,12 +167,13 @@ public function deleteFileSignalement( $suivi = $suiviFactory->createInstanceFrom($this->getUser(), $signalement); /** @var User $user */ $user = $this->getUser(); - $description = $user->getNomComplet().' a supprimé le document suivant :'; + $description = $user->getNomComplet().' a supprimé '; + $description .= File::FILE_TYPE_DOCUMENT === $type ? 'le document suivant :' : 'la photo suivante :'; $suivi->setDescription( $description - .'
    ' + .'
    • ' .$filename - .'
    ' + .'
' ); $suivi->setType(SUIVI::TYPE_AUTO); diff --git a/src/Entity/Intervention.php b/src/Entity/Intervention.php index c2501869d..c8df44b54 100644 --- a/src/Entity/Intervention.php +++ b/src/Entity/Intervention.php @@ -3,6 +3,7 @@ namespace App\Entity; use App\Entity\Behaviour\TimestampableTrait; +use App\Entity\Enum\DocumentType; use App\Entity\Enum\InterventionType; use App\Entity\Enum\ProcedureType; use App\Repository\InterventionRepository; @@ -316,4 +317,14 @@ public function removeFile(File $file): self return $this; } + + /** + * @return Collection + */ + public function getRapportDeVisite(): Collection + { + return $this->files->filter(function (File $file) { + return DocumentType::PROCEDURE_RAPPORT_DE_VISITE === $file->getDocumentType(); + }); + } } diff --git a/src/Manager/SuiviManager.php b/src/Manager/SuiviManager.php index 86fc685dc..2b74c7104 100644 --- a/src/Manager/SuiviManager.php +++ b/src/Manager/SuiviManager.php @@ -4,11 +4,13 @@ use App\Entity\Enum\DocumentType; use App\Entity\File; +use App\Entity\Intervention; use App\Entity\Signalement; use App\Entity\Suivi; use App\Entity\User; use App\EventListener\SignalementUpdatedListener; use App\Factory\SuiviFactory; +use App\Repository\DesordreCritereRepository; use Doctrine\Persistence\ManagerRegistry; use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -21,6 +23,7 @@ public function __construct( private readonly UrlGeneratorInterface $urlGenerator, protected SignalementUpdatedListener $signalementUpdatedListener, protected Security $security, + private DesordreCritereRepository $desordreCritereRepository, string $entityName = Suivi::class ) { parent::__construct($managerRegistry, $entityName); @@ -73,52 +76,97 @@ public function addSuiviIfNeeded( public function createInstanceForFilesSignalement(User $user, Signalement $signalement, array $files): Suivi { - $isRapportDeVisite = false; - $isPhotoDeVisite = false; $nbDocs = 0; $nbPhotos = 0; + /** @var ?DocumentType $documentType */ + $documentType = null; + + /** @var ?Intervention $intervention */ + $intervention = null; foreach ($files as $file) { if (File::FILE_TYPE_PHOTO === $file->getFileType()) { ++$nbPhotos; } else { ++$nbDocs; } + $documentType = $file->getDocumentType(); + $intervention = $file->getIntervention(); + } + $description = ''; + $isVisibleUsager = false; - if (DocumentType::PROCEDURE_RAPPORT_DE_VISITE === $file->getDocumentType()) { - $isRapportDeVisite = true; + if (\array_key_exists($documentType?->value, DocumentType::getProcedureList()) && null === $intervention) { + if ($nbDocs > 0) { + $description .= $nbDocs; + $description .= $nbDocs > 1 ? ' documents partenaires ont été ajoutés' : ' document partenaire a été ajouté'; + $description .= ' au signalement.'; } - if (DocumentType::PHOTO_VISITE === $file->getDocumentType()) { - $isPhotoDeVisite = true; + } + + if (\array_key_exists($documentType?->value, DocumentType::getSituationList())) { + $isVisibleUsager = true; + if ($nbDocs > 0) { + $description .= $nbDocs; + $description .= $nbDocs > 1 ? ' documents ' : ' document '; + $description .= 'sur la situation usager'; + } + + if ($nbPhotos > 0) { + if ('' !== $description) { + $description .= ' et '; + } + $description .= $nbPhotos; + $description .= $nbPhotos > 1 ? ' photos' : ' photo'; + if (null !== $signalement->getCreatedFrom()) { + $description .= ' concernant les désordres suivants'; + } + } + if (0 === $nbDocs && $nbPhotos > 1) { + $description .= ' ont été ajoutées au signalement : '; + } elseif ($nbDocs + $nbPhotos > 1) { + $description .= ' ont été ajoutés au signalement : '; + } elseif (1 === $nbPhotos) { + $description .= ' a été ajoutée au signalement : '; } } - $description = ''; - if ($nbDocs > 0) { - $description .= $nbDocs; - if ($isRapportDeVisite) { + + if (DocumentType::PROCEDURE_RAPPORT_DE_VISITE === $documentType && null !== $intervention) { + $isVisibleUsager = true; + if ($nbDocs > 0) { + $description .= $user->getPartner()->getNom().' a ajouté '; + $description .= $nbDocs; $description .= $nbDocs > 1 ? ' rapports de visite' : ' rapport de visite'; - } else { - $description .= $nbDocs > 1 ? ' documents partenaires' : ' document partenaire'; + $description .= ' de la visite du '.$intervention->getScheduledAt()->format('d/m/Y').' :'; } } - if ($nbPhotos > 0) { - if ('' !== $description) { - $description .= ' et '; - } - $description .= $nbPhotos; - $description .= $nbPhotos > 1 ? ' photos' : ' photo'; - if ($isPhotoDeVisite) { - $description .= ' de visite'; + + if (DocumentType::PHOTO_VISITE === $documentType) { + $isVisibleUsager = true; + if ($nbPhotos > 0) { + $description .= $user->getPartner()->getNom().' a ajouté '; + $description .= $nbPhotos; + $description .= $nbPhotos > 1 ? ' photos' : ' photo'; + $description .= ' de la visite du '.$intervention->getScheduledAt()->format('d/m/Y').' :'; } } - if ($nbDocs + $nbPhotos > 1) { - $description .= ' ont été ajoutés au signalement : '; - } else { - $description .= ' a été ajouté au signalement : '; - } + $descriptionList = []; foreach ($files as $file) { - $fileUrl = $this->urlGenerator->generate('show_uploaded_file', ['folder' => '_up', 'filename' => $file->getFilename()]); - $descriptionList[] = '
  • '.$file->getTitle().'
  • '; + $fileUrl = $this->urlGenerator->generate( + 'show_uploaded_file', + ['folder' => '_up', 'filename' => $file->getFilename()] + ); + $linkFile = '
  • '.$file->getTitle().''; + if (DocumentType::PHOTO_SITUATION === $file->getDocumentType() && null !== $file->getDesordreSlug()) { + $desordreCritere = $this->desordreCritereRepository->findOneBy( + ['slugCritere' => $file->getDesordreSlug()] + ); + if (null !== $desordreCritere) { + $linkFile .= ' ('.$desordreCritere->getLabelCritere().')'; + } + } + $linkFile .= '
  • '; + $descriptionList[] = $linkFile; } $suivi = $this->suiviFactory->createInstanceFrom($user, $signalement); @@ -129,9 +177,7 @@ public function createInstanceForFilesSignalement(User $user, Signalement $signa .'' ); - if ($isRapportDeVisite || $isPhotoDeVisite) { - $suivi->setIsPublic(true); - } + $suivi->setIsPublic($isVisibleUsager); $suivi->setType(SUIVI::TYPE_AUTO); diff --git a/templates/back/signalement/view/visites/visites-buttons.html.twig b/templates/back/signalement/view/visites/visites-buttons.html.twig index 8aefb22d1..7f93941db 100755 --- a/templates/back/signalement/view/visites/visites-buttons.html.twig +++ b/templates/back/signalement/view/visites/visites-buttons.html.twig @@ -20,7 +20,8 @@ {% endif %} {% endif %} {% elseif intervention.status is same as constant('App\\Entity\\Intervention::STATUS_DONE') %} - {% if signalement.interventions is empty or intervention.files is empty %} + {% if signalement.interventions is empty or intervention.files is empty or intervention.getRapportDeVisite is empty%} + {# TODO les photos de visite sont considétées dans ce cas commme un rapport de visite #} {% if isDocumentsEnabled and is_granted('INTERVENTION_EDIT_VISITE', intervention) %}
    -
    - -
    - - -
    +
    + +
    + + +