<?php
declare(strict_types=1);
namespace App\Admin;
use App\Entity\Lot;
use App\Form\SurfaceType;
use App\Service\ImagePdf;
use App\Entity\PieceJointe;
use App\Entity\Programme;
use App\Form\BlockType;
use App\Repository\ProgrammeRepository;
use Sonata\AdminBundle\FieldDescription\FieldDescriptionInterface;
use Sonata\Form\Type\CollectionType;
use Sonata\Form\Type\DatePickerType;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\DatagridInterface;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Sonata\AdminBundle\Route\RouteCollectionInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
final class LotAdmin extends AbstractAdmin
{
protected $datagridValues = [
'_page' => 1,
'_sort_order' => 'DESC',
'_sort_by' => 'id',
'_per_page' => 250,
];
private $tokenStorage;
public function setSecurityTokenStorage($tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function getUser()
{
$token = $this->tokenStorage->getToken();
if (null !== $token) {
return $token->getUser();
}
return null;
}
protected function configureDefaultFilterValues(array &$filterValues): void
{
/*$filterValues['statut'] = [
'type' => null,
'value' => 'libre'
];*/
}
protected function configureDefaultSortValues(array &$sortValues): void
{
$sortValues[DatagridInterface::PAGE] = 1;
$sortValues[DatagridInterface::SORT_ORDER] = 'ASC';
$sortValues[DatagridInterface::SORT_BY] = 'statut';
$sortValues[DatagridInterface::PER_PAGE] = 250;
}
protected function configureBatchActions(array $actions): array
{
if(!in_array("ROLE_SUPERADMIN", $this->getUser()->getRoles()))
unset($actions["delete"]) ;
return $actions;
}
protected function configureRoutes(RouteCollectionInterface $collection): void
{
$collection->remove('show');
$collection->add('clone', $this->getRouterIdParameter() . '/clone');
if ($this->isChild()) {
return;
}
// This is the route configuration as a parent
$collection->clear();
}
public function configureQuery(ProxyQueryInterface $query): ProxyQueryInterface
{
return $query;
}
public function prePersist(object $lot): void
{
$request = $this->getRequest();
$files = $request->files->get($this->getForm()->getName());
if (isset($files['pjs'])) {
$this->managePiecesJointes($files['pjs'], $lot);
}
$programme = $lot->getProgrammeParent();
if ($programme) {
$lot->setAdresse($programme->getAdresse());
$lot->setVille($programme->getVille());
$lot->setCodePostal($programme->getCodePostal());
$lot->setLatitude($programme->getLatitude());
$lot->setLongitude($programme->getLongitude());
$lot->setProgramme($programme->getNom());
$lot->setImage($programme->getImage());
$lot->setBrochure($programme->getBrochure());
$lot->setPlanMasse($programme->getPlanMasse());
$lot->setPromoteur($programme->getPromoteur());
}
}
public function preUpdate(object $lot): void
{
$files = $this->getRequest()->files->get($this->getForm()->getName());
$fields = $this->getRequest()->request->get($this->getForm()->getName());
if(isset($files['pjs'])) $this->managePiecesJointes($files['pjs'], $lot);
}
private function managePiecesJointes($pjs, $lot) {
$lotPjs = $lot->getPjs()->toArray();
foreach($pjs as $n => $pj) {
// Uniquement sur PJ sans fichiers == ajouter dans cette condition ""&& $lot->getPjs()[$n]->getFilename() == null"
if($pj['fichier'] && isset($lotPjs[$n])) {
$fichier = $pj['fichier'];
$originalFilename = pathinfo($fichier->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = $this->slugify($originalFilename);
$newFilename = $safeFilename . '-' . uniqid() . '.' . $fichier->guessExtension();
try {
$fichier->move(PieceJointe::SAVE_PATH, $newFilename);
} catch (FileException $e) {
// ... handle exception if something happens during file upload
}
if(strpos($newFilename, '.pdf') !== false) {
$newFilename = ImagePdf::convertToImage(PieceJointe::SAVE_PATH.$newFilename);
}
$lot->getPjs()[$n]->setFilename($newFilename);
}
}
}
protected function configureDatagridFilters(DatagridMapper $filter): void
{
$filter
->add('reference', null, [
'show_filter' => true,
'label' => 'Réf. LOT'
])
->add('statut', null, [
'show_filter' => true,
'field_type' => ChoiceType::class,
'field_options' => [
'choices' => Lot::getStatutsForForm(),
],
])
->add('typeMoteurRecherche')
->add('promoteur')
->add('superficie')
->add('terrasse')
->add('prix')
->add('fraisNotaireInclus')
->add('annexes')
->add('livraison')
->add('adresse')
->add('ville')
->add('codePostal')
;
}
protected function configureListFields(ListMapper $list): void
{
$list
->addIdentifier('reference', null, [
'label' => 'Réf. LOT',
'route' => ['name' => 'edit'],
'template' => 'sonata/list_fields/list_lot_target_blank.html.twig'
])
->add('_plan', 'string', [
'label' => 'Plan du Lot',
'template' => 'sonata/list_fields/list_lot_target_plan.html.twig',
'sortable' => false,
'mapped' => false,
])
->addIdentifier('etatLot', null, [
'label' => 'Etat de préparation',
'template' => 'sonata/list_fields/list_lot_etat.html.twig'
])
->addIdentifier('statut', null, [
'template' => 'sonata/list_fields/list_lot_statut.html.twig'
])
->addIdentifier('type', null, [
'route' => ['name' => 'edit'],
'template' => 'sonata/list_fields/list_lot_target_blank.html.twig'
])
->addIdentifier('prix', FieldDescriptionInterface::TYPE_INTEGER, [
'template' => 'sonata/list_fields/list_lot_prix.html.twig'
])
->addIdentifier('ville', null, [
'route' => ['name' => 'edit'],
'template' => 'sonata/list_fields/list_lot_target_blank.html.twig'
])
->addIdentifier('codePostal', null, [
'route' => ['name' => 'edit'],
'template' => 'sonata/list_fields/list_lot_target_blank.html.twig'
])
->add('_action', 'actions', [
'actions' => [
'clone' => [
'template' => 'sonata/Button/list__action_clone.html.twig',
],
],
]);
}
protected function configureFormFields(FormMapper $form): void
{
$user = $this->getUser();
$isSuperAdmin = $user->peutModifierContenu();
$isNegociateur = in_array('ROLE_COMMERCIAL', $user->getRoles()) || in_array('ROLE_PARTENAIRE', $user->getRoles());
$authorizedClass = $isSuperAdmin ? '' : 'unauthorized-input';
$lot = $this->getSubject();
$programme = $lot->getProgrammeParent();
$programmeNotes = $programme ? $programme->getNoteGlobale() : '';
$livraisonVisu = $programme ? $programme->getVisuLivraison() : true;
$form
->tab('Lot')
->with('État du lot', ['box_class' => 'inline-fields', 'class' => 'col-lg-6 etats-lots' . ($isSuperAdmin ? '' : ' unauthorized-docs')])
->add('etatLot', ChoiceType::class, [
'choices' => array_flip(Lot::ETATS_PRODUCTION),
'expanded' => true,
'multiple' => false,
'required' => false,
'label_attr' => ['style' => 'display:none;'],
])
->end()
->with('Espace Vide', ['box_class' => 'inline-fields', 'class' => 'col-lg-6 hide-h4'])
->add('placeholder', 'Symfony\Component\Form\Extension\Core\Type\TextType', [
'label' => false,
'attr' => ['style' => 'visibility: hidden;'],
'mapped' => false,
'required' => false,
])
->end()
->with('Description du bien', ['box_class' => 'inline-fields', 'class' => 'col-md-6' . ($isSuperAdmin ? '' : ' unauthorized-docs')])
->add('programmeParent', EntityType::class, [
'class' => Programme::class,
'query_builder' => function (ProgrammeRepository $programmeRepository) {
$user = $this->getUser();
$entreprise = $user->getEntreprise();
return $programmeRepository->createQueryBuilder('p')
->where('p.entreprise = :entreprise')
->setParameter('entreprise', $entreprise);
},
])
->add('reference', null, [
'label' => 'Réf. LOT'
])
// ->add('programme', null, [
// 'required' => true,
// 'attr' => [
// 'placeholder' => 'Ex: Garden park'
// ]
// ])
->add('statut', ChoiceType::class, [
'choices' => [
'Libre' => 'libre',
'Option' => 'option',
'Réservé' => 'reserve',
'Vendu' => 'vendu',
],
'row_attr' => ['class' => $authorizedClass],
])
->add('nature', ChoiceType::class, [
'choices' => [
'Appartement' => 'appartement',
'Maison' => 'maison',
'Terrain' => 'terrain',
'Local commercial' => 'local_commercial'
],
])
->add('type', null, [
'required' => true,
'attr' => [
'style' => 'width:60%',
'placeholder' => 'Ex: T4'
]
])
->add('typeMoteurRecherche', null, [
'label' => 'Type (moteur de recherche)',
'required' => false,
'attr' => [
'style' => 'width:60%',
'placeholder' => 'Ex: T4'
]
])
->add('etage', null, [
'label' => 'Étage',
'attr' => [
'style' => 'width:30%'
]
])
->add('etageMoteurRecherche', null, [
'label' => 'Étage (moteur de recherche)',
'attr' => [
'style' => 'width:30%'
]
])
// ->add('promoteur', null, [
// 'required' => false,
// 'attr' => [
// 'placeholder' => 'Ex: Vinci'
// ]
// ])
->add('orientation', null, [
'required' => false,
'attr' => [
'style' => 'width:80%',
'placeholder' => 'Ex: Sud-est'
]
])
->add('superficie', SurfaceType::class, [
'required' => false
])
->add('terrasse', SurfaceType::class, [
'required' => false,
'help' => 'Laisser vide si pas de terrasse.'
])
->add('terrasse2', SurfaceType::class, [
'label' => '2ème terrasse',
'required' => false,
'help' => 'Laisser vide si pas de 2ème terrasse.'
])
->add('jardin', SurfaceType::class, [
'label' => 'Jardin',
'required' => false,
'help' => 'Laisser vide si pas de jardin.'
])
->add('prix', MoneyType::class, [
'required' => false,
'label' => 'Prix TTC',
'attr' => [
'data-autonumeric' => 'enabled',
],
'row_attr' => ['class' => $authorizedClass],
])
->add('fraisNotaireType', ChoiceType::class, [
'choices' => [
'Frais de notaire réduits' => 'reduits',
'Frais de notaire' => 'standards',
],
'label' => 'Type de frais de notaire'
])
->add('fraisNotaireInclus', MoneyType::class, [
'required' => false,
'label' => 'Frais de notaire',
'attr' => [
'data-autonumeric' => 'enabled'
],
'help' => 'Calcul des frais de notaire automatique.'
])
->add('annexes', null, [
'required' => false,
'label' => 'Annexe(s)',
'attr' => [
'placeholder' => 'Ex: Garage, parking',
],
'row_attr' => ['class' => $authorizedClass],
'help' => 'Laisser vide si pas d\'annexe incluse.'
])
->add('dateLivraison', DatePickerType::class, [
'required' => false,
'label' => 'Date livraison (moteur de recherche)',
'row_attr' => [
'style' => !$livraisonVisu ? 'opacity: 0.75' : ''
],
])
->add('livraison', null, [
'required' => false,
'attr' => [
'placeholder' => 'Ex: 4T '.date('Y'),
],
'row_attr' => [
'class' => $authorizedClass,
'style' => !$livraisonVisu ? 'opacity: 0.75' : ''
],
])
->add('noteGlobaleProgramme', TextareaType::class, [
'label' => 'Notes Globales',
'required' => false,
'data' => $programmeNotes,
'mapped' => false,
'disabled' => true,
'attr' => [
'rows' => '2',
'class' => 'noteglobale',
],
'row_attr' => [
'style' => 'margin-top: 50px;'
],
])
->add('description', TextareaType::class, [
'label' => 'Autres notes sur le lot',
'required' => false,
'attr' => ['rows' => '2'],
'row_attr' => ['class' => $authorizedClass],
])
->end()
->with('Plan du lot', ['box_class' => 'inline-fields', 'class' => 'col-md-6'])
->add('_planLot', BlockType::class, [
'template' => 'sonata/Block/plan_lot.html.twig',
'mapped' => false
])
->end()
->end();
$form
->tab('Slides')
->with('Slides', ['box_class' => 'no-header', 'class' => 'col-md-12' . (!$isNegociateur ? '' : ' unauthorized-docs')])
->add('pjProgression', ChoiceType::class, [
'choices' => array_flip(Lot::INTITULES_PREDEFINIS),
'label_attr' => [
'class' => 'hide'
],
'expanded' => true,
'multiple' => true,
'attr' => [
'class' => 'pjProgression'
]
])
->add('pjs', CollectionType::class, [
'label_attr' => [
'class' => 'hide'
],
'by_reference' => false,
'type_options' => [
'delete' => true,
'delete_options' => [
'type' => ButtonType::class,
'type_options' => [
'label' => 'Retirer',
'attr' => [
'class' => 'btn btn-danger btn-delete-elements',
'onclick' => "
if(confirm('Voulez-vous vraiment effacer cette ligne ? N\'oubliez pas d\'enregistrer vos modifications.')) {
$(this).closest('tr').remove();
}
"
]
]
]
],
'row_attr' => [
'class' => 'lots-slides'
]
], [
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'ordre'
])
->end()
->end()
;
}
public function getExportFormats(): array
{
return ['csv', 'xls'];
}
protected function configureExportFields(): array
{
return [
'programmeParent.nom',
'typeMoteurRecherche',
'promoteur',
'superficie',
'terrasse',
'prix',
'annexes',
'livraison',
'adresse',
'ville',
'codePostal',
'latitude',
'longitude',
'description'
];
}
}