Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[BO - Signalement] Mise à disponibilité des rapports de visite #2314

Merged
merged 7 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions migrations/Version20240304151459.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use App\Entity\Enum\DocumentType;
use App\Entity\File;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20240304151459 extends AbstractMigration
{
public function getDescription(): string
{
return 'rename document types';
}

public function up(Schema $schema): void
{
$this->addSql('UPDATE file SET document_type = \''.DocumentType::PROCEDURE_RAPPORT_DE_VISITE->name.'\' WHERE document_type = \'VISITE\' AND file_type = \''.File::FILE_TYPE_DOCUMENT.'\'');
$this->addSql('UPDATE file SET document_type = \''.DocumentType::PHOTO_VISITE->name.'\' WHERE document_type = \'VISITE\' AND file_type = \''.File::FILE_TYPE_PHOTO.'\'');
$this->addSql('UPDATE file SET document_type = \''.DocumentType::PHOTO_SITUATION->name.'\' WHERE document_type = \'SITUATION\'');
}

public function down(Schema $schema): void
{
}
}
2 changes: 1 addition & 1 deletion src/Controller/Back/SignalementFileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public function editFileSignalement(
$documentType = DocumentType::tryFrom($request->get('documentType'));
if (null !== $documentType) {
$file->setDocumentType($documentType);
if (DocumentType::SITUATION === $documentType) {
if (DocumentType::PHOTO_SITUATION === $documentType) {
$desordreSlug = $request->get('desordreSlug');
$desordreCritereSlugs = $signalement->getDesordreCriteres()->map(
fn (DesordreCritere $desordreCritere) => $desordreCritere->getSlugCritere()
Expand Down
5 changes: 3 additions & 2 deletions src/DataFixtures/Loader/LoadInterventionData.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use App\Repository\PartnerRepository;
use App\Repository\SignalementRepository;
use App\Repository\UserRepository;
use App\Service\ImageManipulationHandler;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
Expand Down Expand Up @@ -67,13 +68,13 @@ private function loadInterventions(ObjectManager $manager, array $row): void
$file = $this->fileFactory->createInstanceFrom(
filename: $document,
title: $document,
type: 'pdf' === pathinfo($document, \PATHINFO_EXTENSION)
type: \in_array(pathinfo($document, \PATHINFO_EXTENSION), ImageManipulationHandler::IMAGE_EXTENSION)
? File::FILE_TYPE_DOCUMENT
: File::FILE_TYPE_PHOTO,
intervention: $intervention,
signalement: $intervention->getSignalement(),
user: $user,
documentType: DocumentType::VISITE
documentType: DocumentType::PROCEDURE_RAPPORT_DE_VISITE
);
$manager->persist($file);
}
Expand Down
5 changes: 3 additions & 2 deletions src/DataFixtures/Loader/LoadSignalementData.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use App\Repository\TagRepository;
use App\Repository\TerritoryRepository;
use App\Repository\UserRepository;
use App\Service\ImageManipulationHandler;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
Expand Down Expand Up @@ -246,7 +247,7 @@ private function loadSignalements(ObjectManager $manager, array $row)
$file = $this->fileFactory->createInstanceFrom(
filename: $document['file'],
title: $document['titre'],
type: 'pdf' === pathinfo($document['file'], \PATHINFO_EXTENSION)
type: \in_array(pathinfo($document['file'], \PATHINFO_EXTENSION), ImageManipulationHandler::IMAGE_EXTENSION)
? File::FILE_TYPE_DOCUMENT
: File::FILE_TYPE_PHOTO,
signalement: $signalement,
Expand Down Expand Up @@ -431,7 +432,7 @@ private function loadNewSignalements(ObjectManager $manager, array $row)
type: File::FILE_TYPE_PHOTO,
signalement: $signalement,
// user: $user,
documentType: DocumentType::SITUATION,
documentType: DocumentType::PHOTO_SITUATION,
desordreSlug: $document['slug']
);
$manager->persist($file);
Expand Down
14 changes: 8 additions & 6 deletions src/Entity/Enum/DocumentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ enum DocumentType: String
case BAILLEUR_DEVIS_POUR_TRAVAUX = 'BAILLEUR_DEVIS_POUR_TRAVAUX';
case BAILLEUR_REPONSE_BAILLEUR = 'BAILLEUR_REPONSE_BAILLEUR';
case AUTRE = 'AUTRE';
case SITUATION = 'SITUATION';
case VISITE = 'VISITE';
case PHOTO_SITUATION = 'PHOTO_SITUATION';
case PHOTO_VISITE = 'PHOTO_VISITE';

public static function getLabelList(): array
{
Expand All @@ -38,16 +38,16 @@ public static function getLabelList(): array
self::BAILLEUR_DEVIS_POUR_TRAVAUX->name => 'Devis pour travaux',
self::BAILLEUR_REPONSE_BAILLEUR->name => 'Réponse bailleur',
self::AUTRE->name => 'Autre',
self::SITUATION->name => 'Photo de désordre',
self::VISITE->name => 'Photo de visite',
self::PHOTO_SITUATION->name => 'Photo de désordre',
self::PHOTO_VISITE->name => 'Photo de visite',
];
}

public static function getPhotosList(): array
{
return [
self::SITUATION->name => self::SITUATION->label(),
self::VISITE->name => self::VISITE->label(),
self::PHOTO_SITUATION->name => self::PHOTO_SITUATION->label(),
self::PHOTO_VISITE->name => self::PHOTO_VISITE->label(),
self::AUTRE->name => self::AUTRE->label(),
];
}
Expand All @@ -66,6 +66,8 @@ 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(),
];
}
Expand Down
15 changes: 15 additions & 0 deletions src/EventSubscriber/InterventionConfirmedSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use App\Service\Signalement\VisiteNotifier;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Workflow\Event\Event;

class InterventionConfirmedSubscriber implements EventSubscriberInterface
Expand All @@ -19,6 +20,7 @@ public function __construct(
private Security $security,
private VisiteNotifier $visiteNotifier,
private SuiviManager $suiviManager,
private UrlGeneratorInterface $urlGenerator,
) {
}

Expand All @@ -45,6 +47,19 @@ public function onInterventionConfirmed(Event $event): void
}
$description .= '<br>Commentaire opérateur :<br>';
$description .= $intervention->getDetails();

if (!$intervention->getFiles()->isEmpty()) {
$description .= '<br>Rapport de visite : ';

$urlDocument = $this->urlGenerator->generate(
'show_uploaded_file',
['filename' => $intervention->getFiles()->first()->getFilename()],
UrlGeneratorInterface::ABSOLUTE_URL
).'?t=___TOKEN___';

$description .= '<a href="'.$urlDocument.'" title="Afficher le document" rel="noopener" target="_blank">Afficher le document</a>';
emilschn marked this conversation as resolved.
Show resolved Hide resolved
}

$isUsagerNotified = $event->getContext()['isUsagerNotified'] ?? true;
$suivi = $this->suiviManager->createSuivi(
user: $currentUser,
Expand Down
15 changes: 15 additions & 0 deletions src/EventSubscriber/InterventionEditedSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
use App\Service\Mailer\NotificationMailerType;
use App\Service\Signalement\VisiteNotifier;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class InterventionEditedSubscriber implements EventSubscriberInterface
{
public function __construct(
private readonly VisiteNotifier $visiteNotifier,
private readonly SuiviManager $suiviManager,
private UrlGeneratorInterface $urlGenerator,
) {
}

Expand All @@ -34,6 +36,19 @@ public function onInterventionEdited(InterventionEditedEvent $event): void
$description = 'Edition de la conclusion de la visite par '.$partnerName.'.<br>';
$description .= 'Commentaire opérateur :<br>';
$description .= $intervention->getDetails();

if (!$intervention->getFiles()->isEmpty()) {
$description .= '<br>Rapport de visite : ';

$urlDocument = $this->urlGenerator->generate(
'show_uploaded_file',
['filename' => $intervention->getFiles()->first()->getFilename()],
UrlGeneratorInterface::ABSOLUTE_URL
).'?t=___TOKEN___';

$description .= '<a href="'.$urlDocument.'" title="Afficher le document" rel="noopener" target="_blank">Afficher le document</a>';
}

$suivi = $this->suiviManager->createSuivi(
user: $currentUser,
signalement: $intervention->getSignalement(),
Expand Down
2 changes: 1 addition & 1 deletion src/Factory/FileFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function createFromFileArray(
?Intervention $intervention = null,
): ?File {
$documentType = SignalementDocumentTypeMapper::map($file['slug']);
$desordreSlug = DocumentType::SITUATION === $documentType ? $file['slug'] : null;
$desordreSlug = DocumentType::PHOTO_SITUATION === $documentType ? $file['slug'] : null;
$fileDescription = $file['description'] ?? null;

return $this->createInstanceFrom(
Expand Down
14 changes: 10 additions & 4 deletions src/Manager/InterventionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
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;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Workflow\WorkflowInterface;
Expand All @@ -30,6 +32,7 @@ public function __construct(
private readonly FileFactory $fileFactory,
private readonly Security $security,
private readonly LoggerInterface $logger,
private readonly FilesystemOperator $fileStorage,
string $entityName = Intervention::class
) {
parent::__construct($managerRegistry, $entityName);
Expand Down Expand Up @@ -209,16 +212,19 @@ private function createFile(Intervention $intervention, string $document): 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: 'pdf' === pathinfo($document, \PATHINFO_EXTENSION)
? File::FILE_TYPE_DOCUMENT
: File::FILE_TYPE_PHOTO,
type: $fileType,
signalement: $intervention->getSignalement(),
user: $user,
documentType: DocumentType::VISITE
documentType: DocumentType::PROCEDURE_RAPPORT_DE_VISITE
);
}
}
2 changes: 1 addition & 1 deletion src/Manager/SignalementManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ public function findSignalementAffectationIterable(
public function getPhotosBySlug(Signalement $signalement, string $desordrePrecisionSlug): ?array
{
$photos = $signalement->getPhotos()->filter(function (File $file) use ($desordrePrecisionSlug) {
return DocumentType::SITUATION === $file->getDocumentType()
return DocumentType::PHOTO_SITUATION === $file->getDocumentType()
&& $file->getDesordreSlug() === $desordrePrecisionSlug;
});

Expand Down
2 changes: 1 addition & 1 deletion src/Service/Signalement/SignalementDocumentTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static function map(string $value): DocumentType
}

if (str_starts_with($value, 'desordres_')) {
return DocumentType::SITUATION;
return DocumentType::PHOTO_SITUATION;
}

if (str_contains($value, 'dpe_bail')) {
Expand Down
2 changes: 1 addition & 1 deletion templates/back/signalement/view/photos-album.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<div>
{% if photo.documentType is not same as null
and photo.documentType is not same as enum('App\\Entity\\Enum\\DocumentType').AUTRE %}
{% if photo.documentType is same as enum('App\\Entity\\Enum\\DocumentType').SITUATION
{% 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) }}
{% else %}
Expand Down
45 changes: 24 additions & 21 deletions templates/back/signalement/view/photos-documents.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@
</div>

{% for index, doc in signalement.files|filter(
doc => doc.fileType == 'document'
and doc.intervention is null
doc => doc.fileType == 'document'
emilschn marked this conversation as resolved.
Show resolved Hide resolved
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))
Expand All @@ -130,33 +129,37 @@
{{ doc.uploadedBy and doc.uploadedBy.partner ? doc.uploadedBy.partner.nom ~ ' - ' : '' }}{{ doc.uploadedBy.nomComplet ?? 'N/R' }}
</div>
<div class="fr-col-12 fr-col-lg-4">
{% if doc.intervention is null %}
<i>{{ doc.title|truncate_filename(45) }}</i>
{% else %}
<i>Rapport de visite du {{ doc.intervention.scheduledAt|date('d/m/Y') }}</i>
{% endif %}
</div>
</div>
</div>
<div class="fr-col-3 fr-text--right">
<a href="{{ asset('_up/'~doc.filename~'/'~signalement.uuid) }}"
class="fr-btn fr-btn--sm fr-icon-eye-fill img-box" title="Afficher le document {{ doc.filename }}"
target="_blank" rel="noopener"></a>
{% if is_granted('FILE_EDIT', doc) %}
{% set DocumentType = enum('\\App\\Entity\\Enum\\DocumentType') %}
{% include 'back/signalement/view/edit-modals/edit-file.html.twig' %}
<button class="fr-btn fr-btn--sm fr-btn--secondary fr-background--white fr-fi-edit-line btn-signalement-file-edit"
id="file_edit_{{ doc.id }}"
title="Editer le document {{ doc.filename }}"
aria-controls="fr-modal-edit-file"
data-fr-opened="false"
data-filename="{{ doc.filename }}"
data-type="document"
data-file-id="{{ doc.id}}"
data-documentType="{{ doc.documentType.name }}"
data-documentType-list="{{ DocumentType.getDocumentsList() | 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' }}"
></button>
{% endif %}
{% if is_granted('FILE_DELETE', doc) %}
{% if is_granted('FILE_EDIT', doc) and doc.intervention is null %}
{% set DocumentType = enum('\\App\\Entity\\Enum\\DocumentType') %}
{% include 'back/signalement/view/edit-modals/edit-file.html.twig' %}
<button class="fr-btn fr-btn--sm fr-btn--secondary fr-background--white fr-fi-edit-line btn-signalement-file-edit"
id="file_edit_{{ doc.id }}"
title="Editer le document {{ doc.filename }}"
aria-controls="fr-modal-edit-file"
data-fr-opened="false"
data-filename="{{ doc.filename }}"
data-type="document"
data-file-id="{{ doc.id}}"
data-documentType="{{ doc.documentType.name }}"
data-documentType-list="{{ DocumentType.getDocumentsList() | 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' }}"
></button>
{% endif %}
{% if is_granted('FILE_DELETE', doc) and doc.intervention is null %}
<button title="Supprimer le document {{ doc.filename }}"
data-delete="{{ path('back_signalement_delete_file',{uuid:signalement.uuid,type:'documents',filename:doc.filename}) }}"
data-token="{{ csrf_token('signalement_delete_file_'~signalement.id) }}"
Expand Down
4 changes: 2 additions & 2 deletions tests/Functional/Manager/FileManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ public function testCreatePhotoVisite(): void
type: File::FILE_TYPE_PHOTO,
signalement: $signalement = $signalementRepository->findOneBy(['reference' => '2023-12']),
description: $desc,
documentType: DocumentType::VISITE
documentType: DocumentType::PROCEDURE_RAPPORT_DE_VISITE
);

$this->assertEquals('blank.jpg', $file->getFilename());
$this->assertEquals('Blank', $file->getTitle());
$this->assertEquals('photo', $file->getFileType());
$this->assertEquals($signalement->getReference(), $file->getSignalement()->getReference());
$this->assertEquals($desc, $file->getDescription());
$this->assertEquals(DocumentType::VISITE, $file->getDocumentType());
$this->assertEquals(DocumentType::PROCEDURE_RAPPORT_DE_VISITE, $file->getDocumentType());
}
}
7 changes: 6 additions & 1 deletion tests/Functional/Manager/InterventionManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
use App\Repository\SignalementRepository;
use App\Service\Signalement\Qualification\SignalementQualificationUpdater;
use Doctrine\Persistence\ManagerRegistry;
use League\Flysystem\FilesystemOperator;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Bundle\SecurityBundle\Security;
Expand All @@ -30,6 +32,7 @@ class InterventionManagerTest extends KernelTestCase
private FileFactory $fileFactory;
private Security $security;
private LoggerInterface $logger;
private MockObject|FilesystemOperator $fileStorage;

private ?InterventionManager $interventionManager = null;

Expand All @@ -48,6 +51,7 @@ protected function setUp(): void
$this->managerRegistry = static::getContainer()->get(ManagerRegistry::class);
$this->signalementRepository = static::getContainer()->get(SignalementRepository::class);
$this->logger = static::getContainer()->get(LoggerInterface::class);
$this->fileStorage = $this->createMock(FilesystemOperator::class);

$this->interventionManager = new InterventionManager(
$this->managerRegistry,
Expand All @@ -57,7 +61,8 @@ protected function setUp(): void
$this->signalementQualificationUpdater,
$this->fileFactory,
$this->security,
$this->logger
$this->logger,
$this->fileStorage
);
}

Expand Down
Loading
Loading