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..582fc87f9 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,11 @@ 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');
+ document.querySelector('#fileDescription').value = target.getAttribute('data-description')
+ document.querySelector('#fr-modal-edit-file-description').classList.remove('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/assets/controllers/back_signalement_view/form_upload_documents.js b/assets/controllers/back_signalement_view/form_upload_documents.js
index 674a3163a..167a1a4ca 100644
--- a/assets/controllers/back_signalement_view/form_upload_documents.js
+++ b/assets/controllers/back_signalement_view/form_upload_documents.js
@@ -1,19 +1,45 @@
-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',
+ '#select-type-situation-to-clone',
+ '#select-type-procedure-to-clone',
+ '#select-desordre-to-clone',
+);
+
+document?.querySelectorAll('.fr-modal-visites-upload-files')?.forEach(modalVisiteUpload => {
+ initializeUploadModal(
+ '#'+modalVisiteUpload.id,
+ null,
+ null,
+ null,
+ )
+})
+
+
+function initializeUploadModal(
+ modalSelector,
+ selectTypeSituationToCloneSelector,
+ selectTypeProcedureToCloneSelector,
+ selectDesordreToCloneSelector,
+) {
+ const modal = document?.querySelector(modalSelector);
+ if (!modal) return;
+
+ 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 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('#btn-validate-modal-upload-files');
+ const ancre = modal.querySelector('#modal-upload-file-dynamic-content');
+
fileSelector.onclick = () => fileSelectorInput.click()
fileSelectorInput.onchange = () => {
@@ -81,7 +107,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 +124,35 @@ 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
- } 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()
+ modal.dataset.hasChanges = true
+ 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{
+ 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
+ if (clone.querySelectorAll('option').length == 1) {
+ clone.remove()
+ } else {
+ div.querySelector('.select-container').appendChild(clone)
+ addEventListenerSelectTypeDesordre(clone)
+ }
} else {
- div.querySelector('.select-container').appendChild(clone)
- addEventListenerSelectTypeDesordre(clone)
+ if (null !== modal.dataset.documentType){
+ let divFileId = div.querySelector('#file-id')
+ divFileId.value = response.response
+ callEditFileRoute(div)
+ addEventListenerDescription(div)
+ }
+
}
btnDeleteTmpFile.href = btnDeleteTmpFile.href.replace('REPLACE', response.response)
btnDeleteTmpFile.classList.remove('fr-hidden', 'delete-html')
@@ -127,8 +168,8 @@ if (modalUploadFiles) {
}
function initInnerHtml(file) {
- var innerHTML =`
+ `
+ if (modal.dataset.documentType == 'PHOTO_VISITE') {
+ innerHTML += `
+
+
+
+
+ `
+ } else{
+ innerHTML += `
+
+
`
+ }
+ innerHTML += `
`
@@ -164,7 +217,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 {
@@ -206,9 +259,41 @@ if (modalUploadFiles) {
})
}
+ 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)
+ })
+ })
+ }
- 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 +302,49 @@ if (modalUploadFiles) {
document.querySelectorAll('a.delete-tmp-file').forEach((button) => {
button.click()
})
- modalUploadFiles.dataset.hasChanges = false
+ modal.dataset.hasChanges = false
})
- let fileType
+ 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 ?? null
+ 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.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') {
- 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', '*/*')
+ }
+ 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) => {
- modalUploadFiles.dataset.validated = true
+ modal.dataset.validated = true
})
-
-
}
\ No newline at end of file
diff --git a/migrations/Version20240329143924.php b/migrations/Version20240329143924.php
new file mode 100644
index 000000000..7e3a275e6
--- /dev/null
+++ b/migrations/Version20240329143924.php
@@ -0,0 +1,31 @@
+addSql('UPDATE file SET file_type = \''.File::FILE_TYPE_DOCUMENT
+ .'\' WHERE document_type = \'SITUATION_FOYER_BAIL\' AND file_type = \''.File::FILE_TYPE_PHOTO.'\'');
+ $this->addSql('UPDATE file SET file_type = \''.File::FILE_TYPE_DOCUMENT
+ .'\' WHERE document_type = \'SITUATION_FOYER_ETAT_DES_LIEUX\' AND file_type = \''.File::FILE_TYPE_PHOTO.'\'');
+ $this->addSql('UPDATE file SET file_type = \''.File::FILE_TYPE_DOCUMENT
+ .'\' WHERE document_type = \'SITUATION_FOYER_DPE\' AND file_type = \''.File::FILE_TYPE_PHOTO.'\'');
+ }
+
+ public function down(Schema $schema): void
+ {
+ }
+}
diff --git a/src/Controller/Back/SignalementController.php b/src/Controller/Back/SignalementController.php
index b1e758bf1..3e6c3c5a2 100755
--- a/src/Controller/Back/SignalementController.php
+++ b/src/Controller/Back/SignalementController.php
@@ -21,6 +21,7 @@
use App\Repository\SignalementQualificationRepository;
use App\Repository\TagRepository;
use App\Security\Voter\UserVoter;
+use App\Service\Signalement\PhotoHelper;
use App\Service\Signalement\SignalementDesordresProcessor;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -178,6 +179,8 @@ public function viewSignalement(
$partnerVisite = $affectationRepository->findAffectationWithQualification(Qualification::VISITES, $signalement);
+ $allPhotosOrdered = PhotoHelper::getSortedPhotos($signalement);
+
return $this->render('back/signalement/view.html.twig', [
'title' => 'Signalement',
'createdFromDraft' => $signalement->getCreatedFrom(),
@@ -206,6 +209,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 4060ee791..14ade9493 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;
@@ -166,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
- .'
'
);
$suivi->setType(SUIVI::TYPE_AUTO);
@@ -214,6 +216,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 +253,17 @@ public function editFileSignalement(
$file->setDocumentType($documentType);
$desordreSlug = $request->get('desordreSlug');
$file->setDesordreSlug($desordreSlug);
+ $interventionId = $request->get('interventionId');
+ if (null !== $interventionId) {
+ $intervention = $interventionRepository->find($interventionId);
+ if ($intervention?->getSignalement() === $file->getSignalement()) {
+ $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/DataFixtures/Files/NewSignalement.yml b/src/DataFixtures/Files/NewSignalement.yml
index c4363ca61..cb02939e1 100644
--- a/src/DataFixtures/Files/NewSignalement.yml
+++ b/src/DataFixtures/Files/NewSignalement.yml
@@ -84,13 +84,18 @@ signalements:
- "desordres_logement_securite_sol_dangereux_pieces_piece_a_vivre"
- "desordres_logement_securite_balcons_pieces_salle_de_bain"
- "desordres_logement_securite_plomb_pieces_salle_de_bain_diagnostique_oui"
- desordre_photos:
+ files:
- file: "Capture-d-ecran-du-2023-06-13-12-58-43-648b2a6b9730f.png"
titre: "Capture-d-ecran-du-2023-06-13-12-58-43-648b2a6b9730f.png"
slug: "desordres_batiment_proprete_interieur"
+ document_type: "PHOTO_SITUATION"
+ - file: "Capture-d-ecran-du-2023-06-13-12-58-43-648b2a6b9730f.png"
+ titre: "Capture-d-ecran-du-2023-06-13-12-58-43-648b2a6b9730f.png"
+ document_type: "AUTRE"
- file: "Capture-d-ecran-du-2023-06-13-12-58-43-648b2a6b9730f.png"
titre: "Capture-d-ecran-du-2023-06-13-12-58-43-648b2a6b9730f.png"
slug: "desordres_logement_chauffage_details_fenetres_permeables"
+ document_type: "PHOTO_SITUATION"
-
territory: "Pas-de-Calais"
uuid: "00000000-0000-0000-2024-000000000002"
diff --git a/src/DataFixtures/Loader/LoadSignalementData.php b/src/DataFixtures/Loader/LoadSignalementData.php
index 56eb37ba3..41919c8f3 100644
--- a/src/DataFixtures/Loader/LoadSignalementData.php
+++ b/src/DataFixtures/Loader/LoadSignalementData.php
@@ -434,16 +434,16 @@ private function loadNewSignalements(ObjectManager $manager, array $row)
$signalement->addSignalementQualification($signalementQualification);
}
}
- if (isset($row['desordre_photos'])) {
- foreach ($row['desordre_photos'] as $document) {
+ if (isset($row['files'])) {
+ foreach ($row['files'] as $document) {
$file = $this->fileFactory->createInstanceFrom(
filename: $document['file'],
title: $document['titre'],
- type: File::FILE_TYPE_PHOTO,
+ type: $document['file_type'] ?? File::FILE_TYPE_PHOTO,
signalement: $signalement,
// user: $user,
- documentType: DocumentType::PHOTO_SITUATION,
- desordreSlug: $document['slug']
+ documentType: DocumentType::tryFrom($document['document_type']) ?? DocumentType::PHOTO_SITUATION,
+ desordreSlug: $document['slug'] ?? null
);
$manager->persist($file);
}
diff --git a/src/Entity/Enum/DocumentType.php b/src/Entity/Enum/DocumentType.php
index 44ba600f3..c6d2b7b53 100644
--- a/src/Entity/Enum/DocumentType.php
+++ b/src/Entity/Enum/DocumentType.php
@@ -3,6 +3,7 @@
namespace App\Entity\Enum;
use App\Entity\Behaviour\EnumTrait;
+use App\Entity\File;
enum DocumentType: String
{
@@ -47,18 +48,25 @@ public static function getPhotosList(): array
{
return [
self::PHOTO_SITUATION->name => self::PHOTO_SITUATION->label(),
- self::PHOTO_VISITE->name => self::PHOTO_VISITE->label(),
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,20 @@ 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(),
];
}
+
+ public function mapFileType(): ?string
+ {
+ return match ($this) {
+ self::SITUATION_FOYER_BAIL, self::SITUATION_FOYER_DPE,
+ self::SITUATION_FOYER_ETAT_DES_LIEUX, self::SITUATION_DIAGNOSTIC_PLOMB_AMIANTE,
+ self::PROCEDURE_MISE_EN_DEMEURE, self::PROCEDURE_RAPPORT_DE_VISITE,
+ self::PROCEDURE_ARRETE_MUNICIPAL, self::PROCEDURE_ARRETE_PREFECTORAL,
+ self::PROCEDURE_SAISINE, self::BAILLEUR_DEVIS_POUR_TRAVAUX,
+ self::BAILLEUR_REPONSE_BAILLEUR, => File::FILE_TYPE_DOCUMENT,
+ self::PHOTO_SITUATION,self::PHOTO_VISITE => File::FILE_TYPE_PHOTO,
+ self::AUTRE => null,
+ };
+ }
}
diff --git a/src/Entity/File.php b/src/Entity/File.php
index 7b51aaf28..a792d9d0c 100644
--- a/src/Entity/File.php
+++ b/src/Entity/File.php
@@ -260,4 +260,11 @@ public function setIsWaitingSuivi(bool $isWaitingSuivi): self
return $this;
}
+
+ public function isSituationPhoto(): bool
+ {
+ return $this->fileType === $this::FILE_TYPE_PHOTO
+ && \array_key_exists($this->documentType->value, DocumentType::getSituationList())
+ && null === $this->intervention;
+ }
}
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/Factory/FileFactory.php b/src/Factory/FileFactory.php
index 191681dcd..df95f27e8 100644
--- a/src/Factory/FileFactory.php
+++ b/src/Factory/FileFactory.php
@@ -78,19 +78,20 @@ public function createFromFileArray(
return $this->createInstanceFrom(
filename: $file['file'],
title: $file['titre'],
- type: $this->getFileType($file),
+ type: $this->getFileType($file, $documentType),
signalement: $signalement,
user: $user,
intervention: $intervention,
- documentType: SignalementDocumentTypeMapper::map($file['slug']),
+ documentType: $documentType,
desordreSlug: $desordreSlug,
description: $fileDescription,
);
}
- private function getFileType(array $file)
+ private function getFileType(array $file, DocumentType $documentType)
{
if ('photos' === $file['key']
+ && File::FILE_TYPE_PHOTO === $documentType->mapFileType()
&& \in_array(
strtolower(pathinfo($file['file'], \PATHINFO_EXTENSION)),
ImageManipulationHandler::IMAGE_EXTENSION
diff --git a/src/Manager/InterventionManager.php b/src/Manager/InterventionManager.php
index 578cb86c8..ad39d2d1c 100644
--- a/src/Manager/InterventionManager.php
+++ b/src/Manager/InterventionManager.php
@@ -13,7 +13,6 @@
use App\Entity\User;
use App\Factory\FileFactory;
use App\Repository\InterventionRepository;
-use App\Service\ImageManipulationHandler;
use App\Service\Signalement\Qualification\SignalementQualificationUpdater;
use Doctrine\Persistence\ManagerRegistry;
use League\Flysystem\FilesystemOperator;
@@ -207,24 +206,22 @@ public function editVisiteFromRequest(VisiteRequest $visiteRequest): ?Interventi
return $intervention;
}
- private function createFile(Intervention $intervention, string $document): File
- {
+ private function createFile(
+ Intervention $intervention,
+ string $document,
+ string $fileType = File::FILE_TYPE_DOCUMENT,
+ DocumentType $documentType = DocumentType::PROCEDURE_RAPPORT_DE_VISITE
+ ): File {
/** @var User $user */
$user = $this->security->getUser();
- $fileType = File::FILE_TYPE_DOCUMENT;
- if (\in_array($this->fileStorage->mimeType($document), ImageManipulationHandler::IMAGE_MIME_TYPES)) {
- $fileType = File::FILE_TYPE_PHOTO;
- }
-
- // TODO : quand la modale sera fait, le documentType pourra être différent
return $this->fileFactory->createInstanceFrom(
filename: $document,
title: $document,
type: $fileType,
signalement: $intervention->getSignalement(),
user: $user,
- documentType: DocumentType::PROCEDURE_RAPPORT_DE_VISITE
+ documentType: $documentType
);
}
}
diff --git a/src/Manager/SignalementManager.php b/src/Manager/SignalementManager.php
index a96d70b4d..e701f1bb6 100644
--- a/src/Manager/SignalementManager.php
+++ b/src/Manager/SignalementManager.php
@@ -13,11 +13,9 @@
use App\Dto\Request\Signalement\SituationFoyerRequest;
use App\Dto\SignalementAffectationListView;
use App\Entity\Affectation;
-use App\Entity\Enum\DocumentType;
use App\Entity\Enum\MotifCloture;
use App\Entity\Enum\ProfileDeclarant;
use App\Entity\Enum\ProprioType;
-use App\Entity\File;
use App\Entity\Model\InformationComplementaire;
use App\Entity\Model\InformationProcedure;
use App\Entity\Model\SituationFoyer;
@@ -804,16 +802,6 @@ public function findSignalementAffectationIterable(
}
}
- public function getPhotosBySlug(Signalement $signalement, string $desordrePrecisionSlug): ?array
- {
- $photos = $signalement->getPhotos()->filter(function (File $file) use ($desordrePrecisionSlug) {
- return DocumentType::PHOTO_SITUATION === $file->getDocumentType()
- && $file->getDesordreSlug() === $desordrePrecisionSlug;
- });
-
- return $photos->toArray();
- }
-
/**
* @todo: Investigate Twig\Error\RuntimeError in ajax request
* Hack: generate csrf token in side server for ajav request
diff --git a/src/Manager/SuiviManager.php b/src/Manager/SuiviManager.php
index 7a79fc8ef..fbe910e27 100644
--- a/src/Manager/SuiviManager.php
+++ b/src/Manager/SuiviManager.php
@@ -2,12 +2,15 @@
namespace App\Manager;
+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;
@@ -20,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);
@@ -74,34 +78,103 @@ public function createInstanceForFilesSignalement(User $user, Signalement $signa
{
$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 = '';
- if ($nbDocs > 0) {
- $description .= $nbDocs;
- $description .= $nbDocs > 1 ? ' documents partenaires' : ' document partenaire';
+ $isVisibleUsager = false;
+
+ 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 ($nbPhotos > 0) {
- if ('' !== $description) {
- $description .= ' et ';
+
+ 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 .= $nbPhotos;
- $description .= $nbPhotos > 1 ? ' photos' : ' photo';
}
- if ($nbDocs + $nbPhotos > 1) {
- $description .= ' ont été ajoutés au signalement : ';
- } else {
- $description .= ' a été ajouté au signalement : ';
+
+ if (DocumentType::PROCEDURE_RAPPORT_DE_VISITE === $documentType && null !== $intervention) {
+ $isVisibleUsager = true;
+ if ($nbDocs > 0) {
+ $description .= sprintf(
+ '%s a ajouté %s %s de la visite du %s :',
+ $user->getPartner()->getNom(),
+ $nbDocs,
+ $nbDocs > 1 ? ' rapports de visite' : ' rapport de visite',
+ $intervention->getScheduledAt()->format('d/m/Y')
+ );
+ }
}
+
+ if (DocumentType::PHOTO_VISITE === $documentType) {
+ $isVisibleUsager = true;
+ if ($nbPhotos > 0) {
+ $description .= sprintf(
+ '%s a ajouté %s %s de la visite du %s :',
+ $user->getPartner()->getNom(),
+ $nbPhotos,
+ $nbPhotos > 1 ? ' photos' : ' photo',
+ $intervention->getScheduledAt()->format('d/m/Y')
+ );
+ }
+ }
+
$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',
+ ['filename' => $file->getFilename()],
+ UrlGeneratorInterface::ABSOLUTE_URL
+ ).'?t=___TOKEN___';
+
+ $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);
@@ -111,6 +184,9 @@ public function createInstanceForFilesSignalement(User $user, Signalement $signa
.implode('', $descriptionList)
.''
);
+
+ $suivi->setIsPublic($isVisibleUsager);
+
$suivi->setType(SUIVI::TYPE_AUTO);
return $suivi;
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/src/Service/Signalement/PhotoHelper.php b/src/Service/Signalement/PhotoHelper.php
new file mode 100644
index 000000000..35a383561
--- /dev/null
+++ b/src/Service/Signalement/PhotoHelper.php
@@ -0,0 +1,66 @@
+getPhotos()->filter(function (File $file) use ($desordrePrecisionSlug) {
+ return DocumentType::PHOTO_SITUATION === $file->getDocumentType()
+ && $file->getDesordreSlug() === $desordrePrecisionSlug;
+ });
+
+ return $photos->toArray();
+ }
+
+ public static function getSortedPhotos(Signalement $signalement): ?array
+ {
+ $photoList = $signalement->getPhotos()->toArray();
+ $photoListByType = [
+ DocumentType::PHOTO_SITUATION->value => [],
+ DocumentType::PHOTO_VISITE->value => [],
+ DocumentType::AUTRE->value => [],
+ ];
+
+ foreach ($photoList as $photoItem) {
+ $type = $photoItem->getDocumentType();
+ $photoListByType[$type->value][] = $photoItem;
+ }
+
+ foreach ($photoListByType as &$photoArray) {
+ usort($photoArray, function (File $fileA, File $fileB) {
+ if (DocumentType::PHOTO_SITUATION === $fileA->getDocumentType()) {
+ return $fileA->getId() <=> $fileB->getId();
+ }
+ if (DocumentType::PHOTO_VISITE === $fileA->getDocumentType()) {
+ $interventionA = $fileA->getIntervention();
+ $interventionB = $fileB->getIntervention();
+ if (null === $interventionA && null === $interventionB) {
+ return 0;
+ }
+ if (null === $interventionA) {
+ return 1;
+ }
+ if (null === $interventionB) {
+ return -1;
+ }
+
+ return $interventionA->getId() <=> $interventionB->getId();
+ }
+
+ return $fileA->getId() <=> $fileB->getId();
+ });
+ }
+
+ return array_merge(
+ $photoListByType[DocumentType::PHOTO_SITUATION->value],
+ $photoListByType[DocumentType::AUTRE->value],
+ $photoListByType[DocumentType::PHOTO_VISITE->value]
+ );
+ }
+}
diff --git a/src/Service/Signalement/SignalementDesordresProcessor.php b/src/Service/Signalement/SignalementDesordresProcessor.php
index e8a1a1255..41feeca4b 100644
--- a/src/Service/Signalement/SignalementDesordresProcessor.php
+++ b/src/Service/Signalement/SignalementDesordresProcessor.php
@@ -67,7 +67,7 @@ private function addPhotoBySlug(
}
$photos[$key] = array_unique(
- array_merge($photos[$key], $this->signalementManager->getPhotosBySlug($signalement, $slug)),
+ array_merge($photos[$key], PhotoHelper::getPhotosBySlug($signalement, $slug)),
\SORT_REGULAR
);
}
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 @@