Commit 1894398b by Julien Jorry

BIG UPDATE : a lot of bug fix + import tool finish + vente != transfert

parent bc174dd5
# PARAMETRES DE L'APPLICATION DE GESTION DE MONNAIE LOCALE COMPLEMENTAIRE
# parameters:
# mlc_name: 'Monnaie locale complémentaire' # Nom complet (< 100 caractères)
# mlc_name_small: 'MLC' # Nom court (< 25 caractères)
# slogan: 'Un outil de gestion de la MLC' # Slogan (< 200 caractères)
\ No newline at end of file
......@@ -27,7 +27,7 @@ sonata_admin:
# inner_list_row: '@SonataAdmin/CRUD/list_inner_row.html.twig'
# base_list_field: '@SonataAdmin/CRUD/base_list_field.html.twig'
list_block: '@SonataAdmin/Block/block_admin_list.html.twig'
# user_block: '@SonataAdmin/Core/user_block.html.twig'
user_block: '@SonataUser/Core/user_block.html.twig'
# add_block: '@SonataAdmin/Core/add_block.html.twig'
# pager_links: '@SonataAdmin/Pager/links.html.twig'
# pager_results: '@SonataAdmin/Pager/results.html.twig'
......
......@@ -3,20 +3,41 @@
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: 'en'
sonata.user.admin.user.controller: 'App\Controller\CRUD\CRUDController'
sonata.media.admin.media.class: 'App\Admin\MediaAdmin'
mlc_title: 'Outil de gestion de monnaie locale complémentaire' # Nom complet (< 100 caractères)
mlc_name: 'Monnaie locale complémentaire' # Nom complet (< 100 caractères)
mlc_name_small: 'MLC' # Nom court (< 25 caractères)
slogan: 'Un outil de gestion de la MLC' # Slogan (< 200 caractères)
cotisation_montant: 10
map_center: '[45.7,3.2]'
map_zoom: 9
map_token: 'pk.eyJ1IjoianVqb3RlIiwiYSI6ImNqc3V3aGl6cTAwdDk0Y3Ftbzg0d2YwajkifQ.VWy1XWkuU9zfHAS7SkgbPA'
favicon_url: '/images/favicon.png'
# PARAMETRES DE L'APPLICATION DE GESTION DE MONNAIE LOCALE COMPLEMENTAIRE
app.mlc_title: 'Outil de gestion de monnaie locale complémentaire' # Nom complet (< 100 caractères)
app.mlc_name: 'Monnaie locale complémentaire' # Nom complet (< 100 caractères)
app.mlc_name_small: 'MLC' # Nom court (< 25 caractères)
app.cotisation_montant: 10
app.map_center: '[45.7,3.2]'
app.map_zoom: 9
app.map_token: 'pk.eyJ1IjoianVqb3RlIiwiYSI6ImNqc3V3aGl6cTAwdDk0Y3Ftbzg0d2YwajkifQ.VWy1XWkuU9zfHAS7SkgbPA'
app.favicon_url: '/images/favicon.png'
app.import.separator: ';'
app.import.header:
groupe:
header: 'name;content;compte'
example: 'Groupe local n°1;<b>Groupe local n°1</b>;123,45'
file: '/csv/groupe.csv'
comptoir:
header: 'groupe;name;content;phone;adresse;cpostal;ville;compte'
example: 'Comptoir n°1;Comptoir n°1;<b>Comptoir n°1</b>;0123456789;2, rue charles de gaulle;12345;Paris;123,45'
file: '/csv/comptoir.csv'
adherent:
header: 'groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte;cotisations'
example: 'Groupe local n°1;Jean;Dupont;jean.dupont@gmail.com;013456789;0612345678;"2; rue Charles de gaulle";12345;Paris;"12,34";"10:2017,10:2018,10:2019"'
file: '/csv/adherent.csv'
prestataire:
header: 'groupe;adresse;cpostal;ville;raison;metier;statut;responsable;iban;siret;web;compte;horaires;description;firstname;lastname;email;phone;mobile;rubriques;cotisations'
example: 'Groupe local n°1;"2; rue Charles de gaulle";12345;Paris;Amap d’exemple;Directeur;SARL;Jean Dupont;FR7630001007941234567890185;732 829 320 00074;www.siteweb.com;"123,45";Dimanche de 8h à 12h;<b>Description du prestataire</b>;Jean;Dupont;jean@gmail.com;0123456789;0612345678;Amap,Fruits,Légumes,Marchés;"10:2017,10:2018,10:2019"'
file: '/csv/prestataire.csv'
# SERVICES
services:
# default configuration for services in *this* file
_defaults:
......@@ -103,6 +124,12 @@ services:
tags:
- { name: kernel.event_subscriber }
app.form.extension.media:
class: App\Form\Extension\MediaTypeExtension
tags:
- { name: form.type_extension }
# - { name: form.type_extension, extended_type: Sonata\MediaBundle\Form\Type\MediaType }
###### Configuration de l'admin ######
admin.adherent.gerer:
......
......@@ -278,7 +278,7 @@ App\Entity\CotisationAdherent:
parenttype: 'cotisation'
type: 'cotisation_adherent'
cotisationInfos: '@cotisationInfos1'
montant: '10'
montant: 10
moyen: 'espece'
expediteur: '@adherent1'
destinataire: '@siege_1'
......@@ -288,7 +288,7 @@ App\Entity\CotisationAdherent:
parenttype: 'cotisation'
type: 'cotisation_adherent'
cotisationInfos: '@cotisationInfos<current()>'
montant: '10'
montant: 10
moyen: 'cb'
expediteur: '@adherent<current()>'
destinataire: '@siege_1'
......@@ -299,7 +299,7 @@ App\Entity\CotisationPrestataire:
parenttype: 'cotisation'
type: 'cotisation_prestataire'
cotisationInfos: '@cotisationInfos<numberBetween(12, 43)>'
montant: '10'
montant: 10
moyen: 'cb'
expediteur: '@prestataire<current()>'
destinataire: '@siege_1'
......
groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte;cotisations
"Groupe local n°1";Jeanne;Dupont;"jeanne.dupont223@gmail.com";013456789;0612345678;"2, rue Charles de gaulle";12345;Paris;"12,34";"10:2017,10:2018,10:2019"
"Groupe local n°4";Jeanne234;Dupont234;"jeanne.dupont12@gmail.com";013456789;0612345678;"234, rue Charles de gaulle";12345;Paris;"12.34";12
\ No newline at end of file
groupe;name;content;phone;adresse;cpostal;ville;compte
"Groupe local n°1";Comptoir n°1;<b>Comptoir n°1</b>;0123456789;"2, rue charles de gaulle";12345;Paris;"123,45"
"Groupe local n°1";Comptoir n°2;<b>Comptoir n°2</b>;0123456789;"2, rue charles de gaulle";12345;Paris;"123,45"
\ No newline at end of file
name;content;compte
Groupe local n11111;<b>Groupe local n°4</b>;123,45
Groupe local n21111;<b>Groupe local n°42</b>;123,45
\ No newline at end of file
groupe;adresse;cpostal;ville;raison;metier;statut;responsable;iban;siret;web;compte;horaires;description;firstname;lastname;email;phone;mobile;rubriques;cotisations
Groupe local n°1;2, rue Charles de gaulle;12345;Paris;Amap d’exemple;Directeur;SARL;Jean Dupont;FR7630001007941234567890185;732 829 320 00074;www.siteweb.com;123,45;Dimanche de 8h à 12h;<b>Description du prestataire</b>;Jean;Dupont;jean@gmail.com;0123456789;0612345678;Amap,Fruits,Légumes,Marchés;13
\ No newline at end of file
......@@ -25,6 +25,7 @@ use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
......@@ -97,10 +98,16 @@ class AdherentAdmin extends AbstractAdmin
$user = $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(User::class)->findOneBy(array('adherent' => $id));
if ($this->isGranted('EDIT') && $user != null) {
$menu->addChild('Edit User', [
$menu->addChild("Modifier l'utilisateur", [
'uri' => $this->getConfigurationPool()->getContainer()->get('router')->generate('admin_app_user_edit', ['id' => $user->getId()], UrlGeneratorInterface::ABSOLUTE_URL)
]);
}
$menu->addChild("Ajouter une cotisation", [
'uri' => $this->getConfigurationPool()->getContainer()->get('router')->generate('cotisation_adherent_create', ['expediteur' => $id], UrlGeneratorInterface::ABSOLUTE_URL)
]);
$menu->addChild("Voir les cotisations", [
'uri' => $this->getConfigurationPool()->getContainer()->get('router')->generate('cotisation_adherent_list', ['filter' => array('expediteur' => array('value' => $id))], UrlGeneratorInterface::ABSOLUTE_URL)
]);
}
/**
......@@ -121,14 +128,14 @@ class AdherentAdmin extends AbstractAdmin
$user->setAdherent($adherent);
$adherent->setUser($user);
}
if (count($adherent->getUser()->getCotisations()) <= 0) {
$cotisation = new Cotisation();
$cotisation->setOperateur($adherent->getUser());
$cotisation->setExpediteur($adherent);
$cotisation->setDebut($now);
$cotisation->setFin(new \DateTime('+ 1 year'));
$adherent->getUser()->addCotisation($cotisation);
}
// if (count($adherent->getUser()->getCotisations()) <= 0) {
// $cotisation = new Cotisation();
// $cotisation->setOperateur($adherent->getUser());
// $cotisation->setExpediteur($adherent);
// $cotisation->setDebut($now);
// $cotisation->setFin(new \DateTime('+ 1 year'));
// $adherent->getUser()->addCotisation($cotisation);
// }
if ($adherent->getGeoloc() == null) {
$adherent->setGeoloc(new Geoloc());
}
......@@ -168,43 +175,43 @@ class AdherentAdmin extends AbstractAdmin
'choice_label' => 'name',
'placeholder' => 'Choisir un groupe',
))
->end()
->with('Cotisation', ['class' => 'col-md-5'])
//@TODO : géré une ou plusieurs cotisations
->add('user.cotisations.first.cotisationInfos.annee', TextType::class, array('label' => 'Année', 'data' => $now->format('Y')))
->add('user.cotisations.first.montant', TextType::class, array('label' => 'Montant'))
->add('user.cotisations.first.moyen', ChoiceType::class, array(
'required' => true,
'label' => 'Moyen :',
'choices' => MoyenEnum::getAvailableTypes(),
'choice_label' => function ($choice) {
return MoyenEnum::getTypeName($choice);
},
));
if ($this->security->getUser()->isGranted('ROLE_TRESORIER')) {
$formMapper
->add('user.cotisations.first.cotisationInfos.recu', CheckboxType::class, array('label' => 'Reçu'));
}
$formMapper->end();
if (!$this->isCurrentRoute('create')) {
$formMapper
->with('Date', ['class' => 'col-md-5'])
->add('user.cotisations.first.cotisationInfos.debut', DateType::class, array(
'label' => 'Date de début',
'data' => new \DateTime(),
'widget' => 'single_text',
'html5' => false,
'attr' => ['class' => 'js-datepicker'],
))
->add('user.cotisations.first.cotisationInfos.fin', DateType::class, array(
'label' => 'Date de fin',
'data' => new \DateTime('+ 1 year'),
'widget' => 'single_text',
'html5' => false,
'attr' => ['class' => 'js-datepicker'],
))
->end();
}
// ->with('Cotisation', ['class' => 'col-md-5'])
// //@TODO : géré une ou plusieurs cotisations
// ->add('user.cotisations.first.cotisationInfos.annee', TextType::class, array('label' => 'Année', 'data' => $now->format('Y')))
// ->add('user.cotisations.first.montant', TextType::class, array('label' => 'Montant'))
// ->add('user.cotisations.first.moyen', ChoiceType::class, array(
// 'required' => true,
// 'label' => 'Moyen :',
// 'choices' => MoyenEnum::getAvailableTypes(),
// 'choice_label' => function ($choice) {
// return MoyenEnum::getTypeName($choice);
// },
// ));
// if ($this->security->getUser()->isGranted('ROLE_TRESORIER')) {
// $formMapper
// ->add('user.cotisations.first.cotisationInfos.recu', CheckboxType::class, array('label' => 'Reçu'));
// }
// $formMapper->end();
// if (!$this->isCurrentRoute('create')) {
// $formMapper
// ->with('Date', ['class' => 'col-md-5'])
// ->add('user.cotisations.first.cotisationInfos.debut', DateType::class, array(
// 'label' => 'Date de début',
// 'data' => new \DateTime(),
// 'widget' => 'single_text',
// 'html5' => false,
// 'attr' => ['class' => 'js-datepicker'],
// ))
// ->add('user.cotisations.first.cotisationInfos.fin', DateType::class, array(
// 'label' => 'Date de fin',
// 'data' => new \DateTime('+ 1 year'),
// 'widget' => 'single_text',
// 'html5' => false,
// 'attr' => ['class' => 'js-datepicker'],
// ))
// ->end();
// }
$formMapper
->with('Addresse', ['class' => 'col-md-7'])
->add('geoloc.adresse', TextType::class, array(
......@@ -222,6 +229,20 @@ class AdherentAdmin extends AbstractAdmin
->end()
->end()
;
$em = $this->getConfigurationPool()->getContainer()->get('doctrine')->getManager();
$formMapper->getFormBuilder()->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($em) {
$adherent = $event->getData();
$user = $adherent->getUser();
if (!$user || null === $user->getId()) {
$repo = $em->getRepository(User::class);
$emailExist = $repo->findBy(array('email' => $user->getEmail()));
if (count($emailExist) > 0) {
$event->getForm()->get('user__email')->addError(new FormError('Courriel déjà utilisé !'));
} else {
$user->setUsername($user->getEmail());
}
}
});
parent::configureFormFields($formMapper);
}
......
......@@ -72,6 +72,9 @@ class CotisationAdherentAdmin extends CotisationAdmin
protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
{
parent::configureDatagridFilters($datagridMapper);
$datagridMapper
->add('expediteur', null, array('label' => 'Adhérent'))
;
}
/**
......@@ -79,6 +82,17 @@ class CotisationAdherentAdmin extends CotisationAdmin
*/
protected function configureFormFields(FormMapper $formMapper): void
{
$expediteurInfos = array(
'label' => 'Expéditeur',
'class' => Adherent::class,
'choices' => $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(Adherent::class)->findOrderByName(),
'placeholder' => 'Choisir un adhérent',
'required' => true,
);
$exp = $this->getRequest()->get('expediteur');
if (!empty($exp)) {
$expediteurInfos['data'] = $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(Adherent::class)->findOneById($exp);
}
$formMapper
->with('Cotisation', ['class' => 'col-md-8'])
->add('reference', HiddenType::class, array(
......@@ -87,13 +101,7 @@ class CotisationAdherentAdmin extends CotisationAdmin
->add('type', HiddenType::class, array(
'data' => 'cotisation_adherent'
))
->add('expediteur', EntityType::class, array(
'label' => 'Expéditeur',
'class' => Adherent::class,
'choices' => $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(Adherent::class)->findOrderByName(),
'placeholder' => 'Choisir un adhérent',
'required' => true,
))
->add('expediteur', EntityType::class, $expediteurInfos)
->add('operateur', HiddenType::class, array(
'data' => $this->security->getUser()->getId(),
'entity_class' => User::class,
......
......@@ -54,8 +54,6 @@ class CotisationAdmin extends AbstractAdmin
->add('cotisationInfos.annee', null, array('label' => 'Année'))
->add('montant', null, array('label' => 'Montant'))
->add('cotisationInfos.recu', null, array('label' => 'Recu ?'))
->add('operateur.username', null, array('label' => 'Login'))
->add('operateur.email', null, array('label' => 'Email'))
;
}
......@@ -80,7 +78,7 @@ class CotisationAdmin extends AbstractAdmin
->add('cotisationInfos.annee', null, array('label' => 'Année', 'data' => $now->format('Y')))
->add('montant', MoneyType::class, array(
'label' => 'Montant',
'data' => $this->container->getParameter('cotisation_montant')
'data' => floatval($this->container->getParameter('app.cotisation_montant'))
))
->add('moyen', ChoiceType::class, array(
'required' => true,
......@@ -143,7 +141,7 @@ class CotisationAdmin extends AbstractAdmin
))
->addIdentifier('operateur', null, array(
'label' => 'Opérateur',
'disabled' => true
// 'disabled' => true
))
;
}
......
......@@ -73,6 +73,9 @@ class CotisationPrestataireAdmin extends CotisationAdmin
protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
{
parent::configureDatagridFilters($datagridMapper);
$datagridMapper
->add('expediteur', null, array('label' => 'Prestataire'))
;
}
......@@ -81,6 +84,17 @@ class CotisationPrestataireAdmin extends CotisationAdmin
*/
protected function configureFormFields(FormMapper $formMapper): void
{
$expediteurInfos = array(
'label' => 'Expéditeur',
'class' => Prestataire::class,
'choices' => $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(Prestataire::class)->findBy(array('enabled' => true), array('raison'=> 'ASC')),
'placeholder' => 'Choisir un prestataire',
'required' => true,
);
$exp = $this->getRequest()->get('expediteur');
if (!empty($exp)) {
$expediteurInfos['data'] = $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(Prestataire::class)->findOneById($exp);
}
$formMapper
->with('Cotisation', ['class' => 'col-md-8'])
->add('reference', HiddenType::class, array(
......@@ -89,13 +103,7 @@ class CotisationPrestataireAdmin extends CotisationAdmin
->add('type', HiddenType::class, array(
'data' => 'cotisation_prestataire'
))
->add('expediteur', EntityType::class, array(
'label' => 'Expéditeur',
'class' => Prestataire::class,
'choices' => $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(Prestataire::class)->findBy(array('enabled' => true), array('raison'=> 'ASC')),
'placeholder' => 'Choisir un prestataire',
'required' => true,
))
->add('expediteur', EntityType::class, $expediteurInfos)
->add('operateur', HiddenType::class, array(
'data' => $this->security->getUser()->getId(),
'entity_class' => User::class,
......
......@@ -31,6 +31,7 @@ use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
......@@ -102,10 +103,16 @@ class PrestataireAdmin extends AbstractAdmin
$user = $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(User::class)->findOneBy(array('prestataire' => $id));
if ($this->isGranted('EDIT') && $user != null) {
$menu->addChild('Edit User', [
$menu->addChild("Modifier l'utilisateur", [
'uri' => $this->getConfigurationPool()->getContainer()->get('router')->generate('admin_app_user_edit', ['id' => $user->getId()], UrlGeneratorInterface::ABSOLUTE_URL)
]);
}
$menu->addChild("Ajouter une cotisation", [
'uri' => $this->getConfigurationPool()->getContainer()->get('router')->generate('cotisation_prestataire_create', ['expediteur' => $id], UrlGeneratorInterface::ABSOLUTE_URL)
]);
$menu->addChild("Voir les cotisations", [
'uri' => $this->getConfigurationPool()->getContainer()->get('router')->generate('cotisation_prestataire_list', ['filter' => array('expediteur' => array('value' => $id))], UrlGeneratorInterface::ABSOLUTE_URL)
]);
}
/**
......@@ -131,14 +138,14 @@ class PrestataireAdmin extends AbstractAdmin
$user->setPrestataire($presta);
$presta->setUser($user);
}
if (count($presta->getUser()->getCotisations()) <= 0) {
$cotisation = new Cotisation();
$cotisation->setOperateur($presta->getUser());
$cotisation->setExpediteur($presta);
$cotisation->setDebut($now);
$cotisation->setFin(new \DateTime('+ 1 year'));
$user->addCotisation($cotisation);
}
// if (count($presta->getUser()->getCotisations()) <= 0) {
// $cotisation = new Cotisation();
// $cotisation->setOperateur($presta->getUser());
// $cotisation->setExpediteur($presta);
// $cotisation->setDebut($now);
// $cotisation->setFin(new \DateTime('+ 1 year'));
// $presta->getUser()->addCotisation($cotisation);
// }
if ($presta->getGeoloc() == null) {
$presta->setGeoloc(new Geoloc());
}
......@@ -166,17 +173,17 @@ class PrestataireAdmin extends AbstractAdmin
))
->add('user.firstname', TextType::class, array(
'label' => 'Prénom :',
'required' => true
'required' => false
))
->add('user.lastname', TextType::class, array(
'label' => 'Nom :',
'required' => true
'required' => false
));
if (!$this->isCurrentRoute('create')) {
$formMapper
->add('user.username', TextType::class, array(
'label' => 'Username :',
'required' => true,
'required' => false,
'disabled' => true
));
}
......@@ -261,71 +268,74 @@ class PrestataireAdmin extends AbstractAdmin
'required' => false
))
->end();
if ($cotisation != null) {
//@TODO : cotisationS
$formMapper
->with('Cotisation', ['class' => 'col-md-5'])
->add('user.cotisations.last.cotisationInfos.annee', TextType::class, array('label' => 'Année', 'data' => $now->format('Y')))
->add('user.cotisations.last.montant', MoneyType::class, array(
'label' => 'Montant',
'data' => $this->getConfigurationPool()->getContainer()->getParameter('cotisation_montant')
))
->add('user.cotisations.last.moyen', ChoiceType::class, array(
'required' => true,
'label' => 'Moyen :',
'choices' => MoyenEnum::getAvailableTypes(),
'choice_label' => function ($choice) {
return MoyenEnum::getTypeName($choice);
},
))
->add('user.cotisations.last.cotisationInfos.recu', CheckboxType::class, array(
'label' => 'Reçu',
'required' => false
))
->end();
if (!$this->isCurrentRoute('create')) {
$formMapper
->with('Date', ['class' => 'col-md-5'])
->add('user.cotisations.last.cotisationInfos.debut', DateType::class, array(
'label' => 'Date de début',
'data' => new \DateTime(),
'widget' => 'single_text',
'html5' => false,
'attr' => ['class' => 'js-datepicker'],
))
->add('user.cotisations.last.cotisationInfos.fin', DateType::class, array(
'label' => 'Date de fin',
'data' => new \DateTime('+ 1 year'),
'widget' => 'single_text',
'html5' => false,
'attr' => ['class' => 'js-datepicker'],
))
->end();
}
} else {
$formMapper
->end()
->tab('Cotisation')
->with('Cotisations', ['class' => 'col-md-12'])
->add('user.cotisations', CollectionType::class, array(
'entry_type' => CotisationFormType::class,
'data' => $presta->getUser()->getCotisations(),
'entry_options' => array(
// 'class' => Cotisation::class,
// 'choices' => $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(CotisationPrestataire::class)->findBy(array('expediteur' => $presta)),
// 'choice_label' => 'reference',
// 'placeholder' => 'Cotisation',
// 'required' => false,
'label' => false
),
'by_reference' => false,
'allow_add' => false,
'allow_delete' => false,
), array(
'admin_code' => 'admin.prestataire.cotisations'
))
->end()
;
// if ($cotisation != null) {
// //@TODO : cotisationS
// $formMapper
// ->with('Cotisation', ['class' => 'col-md-5'])
// ->add('user.cotisations.last.cotisationInfos.annee', TextType::class, array('label' => 'Année', 'data' => intval($now->format('Y'))))
// ->add('user.cotisations.last.montant', MoneyType::class, array(
// 'label' => 'Montant',
// 'empty_data' => floatval($this->getConfigurationPool()->getContainer()->getParameter('app.cotisation_montant'))
// ))
// ->add('user.cotisations.last.moyen', ChoiceType::class, array(
// 'required' => true,
// 'label' => 'Moyen :',
// 'choices' => MoyenEnum::getAvailableTypes(),
// 'choice_label' => function ($choice) {
// return MoyenEnum::getTypeName($choice);
// },
// ))
// ->add('user.cotisations.last.cotisationInfos.recu', CheckboxType::class, array(
// 'label' => 'Reçu',
// 'required' => false
// ))
// ->end();
// if (!$this->isCurrentRoute('create')) {
// $formMapper
// ->with('Date', ['class' => 'col-md-5'])
// ->add('user.cotisations.last.cotisationInfos.debut', DateType::class, array(
// 'label' => 'Date de début',
// 'data' => new \DateTime(),
// 'widget' => 'single_text',
// 'html5' => false,
// 'attr' => ['class' => 'js-datepicker'],
// ))
// ->add('user.cotisations.last.cotisationInfos.fin', DateType::class, array(
// 'label' => 'Date de fin',
// 'data' => new \DateTime('+ 1 year'),
// 'widget' => 'single_text',
// 'html5' => false,
// 'attr' => ['class' => 'js-datepicker'],
// ))
// ->end();
// }
// } else {
// if (count($presta->getUser()->getCotisations()) > 0) {
// $formMapper
// ->end()
// ->tab('Cotisation')
// ->with('Cotisations', ['class' => 'col-md-12'])
// ->add('user.cotisations', CollectionType::class, array(
// 'entry_type' => CotisationFormType::class,
// // 'data' => $presta->getUser()->getCotisations(),
// // 'entry_options' => array(
// // // 'class' => Cotisation::class,
// // // 'choices' => $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(CotisationPrestataire::class)->findBy(array('expediteur' => $presta)),
// // // 'choice_label' => 'reference',
// // // 'placeholder' => 'Cotisation',
// // // 'required' => false,
// // 'label' => false
// // ),
// 'by_reference' => false,
// 'allow_add' => false,
// 'allow_delete' => false,
// 'disabled' => true,
// ), array(
// 'admin_code' => 'admin.prestataire.cotisations'
// ))
// ->end()
// ;
// }
// $formMapper
// ->tab('Cotisation '.$cotisation->getAnnee())
// ->with('Cotisation', ['class' => 'col-md-5'])
......@@ -358,8 +368,22 @@ class PrestataireAdmin extends AbstractAdmin
// ))
// ->end()
// ;
}
$formMapper->end();
$em = $this->getConfigurationPool()->getContainer()->get('doctrine')->getManager();
$formMapper->getFormBuilder()->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($em) {
$prestataire = $event->getData();
$user = $prestataire->getUser();
if (!$user || null === $user->getId()) {
$repo = $em->getRepository(User::class);
$emailExist = $repo->findBy(array('email' => $user->getEmail()));
if (count($emailExist) > 0) {
$event->getForm()->get('user__email')->addError(new FormError('Courriel déjà utilisé !'));
} else {
$user->setUsername($user->getEmail());
}
}
});
parent::configureFormFields($formMapper);
}
......@@ -405,6 +429,15 @@ class PrestataireAdmin extends AbstractAdmin
;
}
public function getTemplate($name)
{
if ($name == 'edit') {
return 'presta/block/base_edit_prestataires.html.twig';
}
return parent::getTemplate($name);
}
/**
* @param UserManagerInterface $userManager
*/
......
......@@ -154,7 +154,7 @@ class UserAdmin extends BaseUserAdmin
'translation_domain' => $this->getTranslationDomain(),
];
// NEXT_MAJOR: Remove this when dropping support for SF 2.8
// w: Remove this when dropping support for SF 2.8
if (method_exists(FormTypeInterface::class, 'setDefaultOptions')) {
$genderOptions['choices_as_values'] = true;
}
......@@ -164,11 +164,15 @@ class UserAdmin extends BaseUserAdmin
->tab('User')
->with('General')
->add('username')
->add('email')
->add('email');
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
$formMapper
->add('plainPassword', TextType::class, [
'required' => (!$this->getSubject() || null === $this->getSubject()->getId()),
'required' => (!$this->getSubject() || null === $this->getSubject()->getId())
])
->end()
;
}
$formMapper->end()
->with('Profile')
// ->add('dateOfBirth', DatePickerType::class, [
// 'years' => range(1900, $now->format('Y')),
......
......@@ -9,6 +9,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route;
class AdminController extends Controller
......@@ -74,4 +75,31 @@ class AdminController extends Controller
}
return new JsonResponse(array('status' => $status, 'newvalue' => ($object->getReconverti()?'true':'false')));
}
/**
* @Route("/admin/getcsv", name="getcsv")
*/
public function getCsvAction(Request $request)
{
$data = $request->get('data');
$header = $request->get('header');
$response = new StreamedResponse();
$response->setCallback(function () use ($data, $header) {
$handle = fopen('php://output', 'w+');
// Nom des colonnes du CSV
fputcsv($handle, explode(';', $header), ';');
//Champs
foreach ($data as $row) {
// fwrite($handle, $row);
fputcsv($handle, explode(';', $row), ';');
}
fclose($handle);
});
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment; filename="export.csv"');
return $response;
}
}
<?php
namespace App\Controller;
use App\Entity\Adherent;
use App\Entity\Comptoir;
use App\Entity\Cotisation;
use App\Entity\Geoloc;
use App\Entity\Groupe;
use App\Entity\Import;
use App\Entity\Prestataire;
use App\Entity\Rubrique;
use App\Entity\Siege;
use App\Entity\User;
use App\Entity\Usergroup;
use App\Enum\MoyenEnum;
use App\Form\Type\ImportFormType;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\UserManipulator;
use Sonata\AdminBundle\Controller\CRUDController;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Translation\TranslatorInterface;
class ImportController extends CRUDController
{
protected $siege;
protected $header;
protected $warnings;
protected $errors;
protected $success;
protected $lineErrors;
protected $em;
protected $file;
protected $security;
protected $userManager;
protected $translator;
public function __construct(EntityManagerInterface $em, Security $security, UserManagerInterface $userManager, TranslatorInterface $translator)
{
$this->header = null;
$this->warnings = array();
$this->errors = array();
$this->lineErrors = array();
$this->em = $em;
$this->security = $security;
$this->userManager = $userManager;
$this->translator = $translator;
$this->siege = null;
}
public function listAction()
{
$this->siege = $this->em->getRepository(Siege::class)->findOneById(1);
$import = new Import();
$import->setUser($this->getUser());
$form = $this->createForm(ImportFormType::class, $import);
......@@ -21,23 +63,16 @@ class ImportController extends CRUDController
if ($form->isSubmitted() && $form->isValid()) {
$import = $form->getData();
$media = $import->getMedia();
$provider = $this->getProvider($media);
// Sauvegarder l'import en base de données avant l'essai d'import
$this->em->persist($import);
$this->em->flush();
$idimport = $import->getId();
// TODO : finir import data from file
$data = $this->parseCSV($provider->generatePath($media), $media->getProviderReference());
$batchSize = 20;
$cptLigne = 1;
$errors = [];
// Processing on each row of data
foreach ($data as $row) {
// @TODO
}
$this->importFromCSV($media);
if (empty($errors)) {
if (empty($this->errors)) {
$import = $this->em->getRepository(Import::class)->findOneById($idimport);
$import->setEnabled(true);
$this->em->persist($import);
$this->em->flush();
......@@ -45,45 +80,559 @@ class ImportController extends CRUDController
'success',
'Import effectué avec succès !'
);
$referer = $this->getRequest()->headers->get('referer');
if ($referer && !$this->getRequest()->isXmlHttpRequest()) {
return $this->redirect($referer);
} elseif (!$this->getRequest()->isXmlHttpRequest()) {
return new Response('', Response::HTTP_BAD_REQUEST);
}
} else {
$this->addFlash(
'error',
'Import effectué avec succès !'
);
}
}
return $this->renderWithExtraParams('admin/import.html.twig', array(
'action' => 'list',
'form' => $form->createView()
'form' => $form->createView(),
'errors' => $this->errors,
'warnings' => $this->warnings,
'success' => $this->success,
'linkcsverror' => (count($this->lineErrors) > 0)?$this->generateUrl('getcsv', array('header' => $this->header, 'data' => array_values($this->lineErrors))):null,
'csvparams' => $this->getParameter('app.import.header')
));
}
private function importFromCSV($media)
{
// Turning off doctrine default logs queries for saving memory
$this->em->getConnection()->getConfiguration()->setSQLLogger(null);
// // Get file provider
$provider = $this->container->get($media->getProviderName());
$csvRows = $this->parseCSV($provider->getFilesystem()->getAdapter()->getDirectory(), $provider->getReferenceImage($media));
$this->header = implode(';', array_values($csvRows[0]));
// dump($csvRows);
// dump($header);
// exit();
$config = $this->getParameter('app.import.header');
if ($this->header == $config['adherent']['header']) {
$result = $this->importAdherent($csvRows);
} else if ($this->header == $config['prestataire']['header']) {
$result = $this->importPrestataire($csvRows);
} else if ($this->header == $config['groupe']['header']) {
$result = $this->importGroupe($csvRows);
} else if ($this->header == $config['comptoir']['header']) {
$result = $this->importComptoir($csvRows);
} else {
$this->errors['error'] = $this->translator->trans('CSV invalide');
}
return $result;
}
private function importComptoir($csvRows)
{
// Iterate over the reader and write each row to the database
// groupe;name;content;phone;mobile;adresse;cpostal;ville;compte
$line = 0;
foreach ($csvRows as $row) {
if ($line == 0) {
$line++;
continue;
}
$groupe = $row['groupe'];
$name = $row['name'];
$content = $row['content'];
$phone = $row['phone'];
$adresse = $row['adresse'];
$cpostal = $row['cpostal'];
$ville = $row['ville'];
$compte = $row['compte'];
if (empty($groupe) && empty($name)) {
$this->addError($row, $line, 'email & groupe', $this->translator->trans("L'email et le groupe sont obligatoires !"));
$line++;
continue;
}
$comptoir = $this->em->getRepository(Comptoir::class)->findOneBy(array('name' => $name, 'groupe' => $groupe));
if (empty($comptoir)) {
$comptoir = new Comptoir();
if (!empty($groupe)) {
$groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(array('name' => $groupe));
if (empty($groupeFound)) {
$groupeFound = new Groupe();
$groupeFound->setName($groupe);
$groupeFound->setSiege($this->siege);
$this->em->persist($groupeFound);
$this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ').$groupe);
}
$comptoir->setGroupe($groupeFound);
}
if (!empty($name)) {
$comptoir->setName($name);
} else {
$this->addWarning($row, $line, 'name', 'empty');
}
if (!empty($content)) {
$comptoir->setContent($content);
} else {
$this->addWarning($row, $line, 'content', 'empty');
}
if (!empty($phone)) {
$comptoir->setTel($phone);
} else {
$this->addWarning($row, $line, 'phone', 'empty');
}
if (!empty($compte)) {
$comptoir->setCompte($this->tofloat($compte));
} else {
$this->addWarning($row, $line, 'compte', 'empty');
}
if (!empty($adresse) || !empty($cpostal) || !empty($ville)) {
$geolocFound = new Geoloc();
$geolocFound->setAdresse($adresse);
$geolocFound->setCpostal(intval($cpostal));
$geolocFound->setVille($ville);
$comptoir->setGeoloc($geolocFound);
}
$this->addSuccess($row, $line, 'comptoir', $this->translator->trans('Comptoir ajouté : ').$name);
$this->em->persist($comptoir);
$this->em->flush();
$this->em->clear();
} else {
$this->addError($row, $line, 'name', $this->translator->trans("Le comptoir avec ce nom '".$name."' existe déjà !"));
}
$line++;
}
ksort($this->errors);
ksort($this->warnings);
}
private function importGroupe($csvRows)
{
// Iterate over the reader and write each row to the database
// name;content;compte
$line = 0;
foreach ($csvRows as $row) {
if ($line == 0) {
$line++;
continue;
}
$name = $row['name'];
$content = $row['content'];
$compte = $row['compte'];
$groupe = $this->em->getRepository(Groupe::class)->findOneBy(array('name' => $name));
if (empty($groupe)) {
$groupe = new Groupe();
$groupe->setSiege($this->em->getRepository(Siege::class)->findOneById(1));
if (!empty($name)) {
$groupe->setName($name);
} else {
$this->addWarning($row, $line, 'name', 'empty');
}
if (!empty($content)) {
$groupe->setContent($content);
} else {
$this->addWarning($row, $line, 'content', 'empty');
}
if (!empty($compte)) {
$groupe->setCompte($this->tofloat($compte));
} else {
$this->addWarning($row, $line, 'compte', 'empty');
}
$this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ').$name);
$this->em->persist($groupe);
$this->em->flush();
$this->em->clear();
} else {
$this->addError($row, $line, 'name', $this->translator->trans("Le groupe avec ce nom '".$name."' existe déjà !"));
}
$line++;
}
ksort($this->errors);
ksort($this->warnings);
}
private function importPrestataire($csvRows)
{
// Iterate over the reader and write each row to the database
// groupe;adresse;cpostal;ville;raison;metier;statut;responsable;iban;siret;web;compte;horaires;description;firstname;lastname;email;phone;mobile;rubriques
$line = 0;
foreach ($csvRows as $row) {
$hasError = false;
if ($line == 0) {
$line++;
continue;
}
$groupe = $row['groupe'];
$adresse = $row['adresse'];
$cpostal = $row['cpostal'];
$ville = $row['ville'];
$raison = $row['raison'];
$metier = $row['metier'];
$statut = $row['statut'];
$responsable = $row['responsable'];
$iban = $row['iban'];
$siret = $row['siret'];
$web = $row['web'];
$compte = $row['compte'];
$horaires = $row['horaires'];
$description = $row['description'];
$firstname = $row['firstname'];
$lastname = $row['lastname'];
$email = $row['email'];
$phone = $row['phone'];
$mobile = $row['mobile'];
$rubriques = $row['rubriques'];
$prestataire = new Prestataire();
$user = $this->userManager->createUser();
$user->setEnabled(true);
$user->setPassword(md5(random_bytes(10)));
$user->addRole('ROLE_PRESTATAIRE');
$usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Prestataire');
$user->addGroup($usergroupe);
$user->setPrestataire($prestataire);
$prestataire->setUser($user);
if (!empty($raison)) {
$prestataire->setRaison($raison);
} else {
$this->addWarning($row, $line, 'raison', 'empty');
}
if (!empty($metier)) {
$prestataire->setMetier($metier);
} else {
$this->addWarning($row, $line, 'metier', 'empty');
}
if (!empty($statut)) {
$prestataire->setStatut($statut);
} else {
$this->addWarning($row, $line, 'statut', 'empty');
}
if (!empty($responsable)) {
$prestataire->setResponsable($responsable);
} else {
$this->addWarning($row, $line, 'responsable', 'empty');
}
if (!empty($iban)) {
$prestataire->setIban($iban);
} else {
$this->addWarning($row, $line, 'iban', 'empty');
}
if (!empty($siret)) {
$prestataire->setSiret($siret);
} else {
$this->addWarning($row, $line, 'siret', 'empty');
}
if (!empty($web)) {
$prestataire->setWeb($web);
} else {
$this->addWarning($row, $line, 'web', 'empty');
}
if (!empty($horaires)) {
$prestataire->setHoraires($horaires);
} else {
$this->addWarning($row, $line, 'horaires', 'empty');
}
if (!empty($description)) {
$prestataire->setDescription($description);
} else {
$this->addWarning($row, $line, 'description', 'empty');
}
if (!empty($firstname)) {
$user->setFirstname($firstname);
} else {
$this->addWarning($row, $line, 'firstname', 'empty');
}
if (!empty($lastname)) {
$user->setLastname($lastname);
} else {
$this->addWarning($row, $line, 'lastname', 'empty');
}
if (!empty($email)) {
$userFound = $this->em->getRepository(User::class)->findOneBy(array('email' => $email));
if (!empty($userFound)) {
$hasError = true;
$this->addError($row, $line, 'email', $this->translator->trans("L'email est déjà utilisé !"));
$line++;
continue;
} else {
$user->setEmail($email);
$user->setUsername($email);
}
} else {
$this->addWarning($row, $line, 'email', 'empty');
}
if (!empty($phone)) {
$user->setPhone($phone);
} else {
$this->addWarning($row, $line, 'phone', 'empty');
}
if (!empty($mobile)) {
$user->setMobile($mobile);
} else {
$this->addWarning($row, $line, 'mobile', 'empty');
}
if (!empty($compte)) {
$prestataire->setCompte($this->tofloat($compte));
} else {
$this->addWarning($row, $line, 'compte', 'empty');
}
if (!empty($groupe)) {
$groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(array('name' => $groupe));
if (empty($groupeFound)) {
$groupeFound = new Groupe();
$groupeFound->setName($groupe);
$groupeFound->setSiege($this->siege);
$this->em->persist($groupeFound);
$this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ').$groupe);
}
$prestataire->setGroupe($groupeFound);
} else {
$this->addWarning($row, $line, 'groupe', 'empty');
}
if (!empty($rubriques)) {
$rubriquesArray = explode(',', $rubriques);
foreach ($rubriquesArray as $rubrique) {
$rubriquesFound = $this->em->getRepository(Rubrique::class)->findOneBy(array('name' => $rubrique));
if (empty($rubriquesFound)) {
$rubriquesFound = new Rubrique();
$rubriquesFound->setName($rubrique);
$this->em->persist($rubriquesFound);
$this->addSuccess($row, $line, 'rubrique', $this->translator->trans('Rubrique ajoutée : ').$rubrique);
}
}
} else {
$this->addWarning($row, $line, 'rubriques', 'empty');
}
if (!empty($adresse) || !empty($cpostal) || !empty($ville)) {
$geolocFound = new Geoloc();
$geolocFound->setAdresse($adresse);
$geolocFound->setCpostal(intval($cpostal));
$geolocFound->setVille($ville);
$prestataire->setGeoloc($geolocFound);
}
if (!$hasError) {
$this->addSuccess($row, $line, 'user', $this->translator->trans('Prestataire bien ajouté : ').$user->__toString());
$this->userManager->updateUser($user);
$this->em->persist($user);
$this->em->flush();
$this->em->clear();
}
$line++;
}
ksort($this->errors);
ksort($this->warnings);
}
private function importAdherent($csvRows)
{
// Iterate over the reader and write each row to the database
// groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte
$line = 0;
foreach ($csvRows as $row) {
$hasError = false;
if ($line == 0) {
$line++;
continue;
}
$groupe = $row['groupe'];
$firstname = $row['firstname'];
$lastname = $row['lastname'];
$email = $row['email'];
$phone = $row['phone'];
$mobile = $row['mobile'];
$adresse = $row['adresse'];
$cpostal = $row['cpostal'];
$ville = $row['ville'];
$ecompte = $row['ecompte'];
$cotisations = $row['cotisations'];
$adherent = new Adherent();
$user = $this->userManager->createUser();
$user->setEnabled(true);
$user->setPassword(md5(random_bytes(10)));
$user->addRole('ROLE_ADHERENT');
$usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent');
$user->addGroup($usergroupe);
$user->setAdherent($adherent);
$adherent->setUser($user);
if (!empty($firstname)) {
$user->setFirstname($firstname);
} else {
$this->addWarning($row, $line, 'firstname', 'empty');
}
if (!empty($lastname)) {
$user->setLastname($lastname);
} else {
$this->addWarning($row, $line, 'lastname', 'empty');
}
if (!empty($email)) {
$userFound = $this->em->getRepository(User::class)->findOneBy(array('email' => $email));
if (!empty($userFound)) {
$hasError = true;
$this->addError($row, $line, 'email', $this->translator->trans("L'email est déjà utilisé !"));
$line++;
continue;
} else {
$user->setEmail($email);
$user->setUsername($email);
}
} else {
$this->addWarning($row, $line, 'email', 'empty');
}
if (!empty($phone)) {
$user->setPhone($phone);
} else {
$this->addWarning($row, $line, 'phone', 'empty');
}
if (!empty($mobile)) {
$user->setMobile($mobile);
} else {
$this->addWarning($row, $line, 'mobile', 'empty');
}
if (!empty($ecompte)) {
$adherent->setEcompte($this->tofloat($ecompte));
} else {
$this->addWarning($row, $line, 'ecompte', 'empty');
}
if (!empty($groupe)) {
$groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(array('name' => $groupe));
if (empty($groupeFound)) {
$groupeFound = new Groupe();
$groupeFound->setName($groupe);
$groupeFound->setSiege($this->siege);
$this->em->persist($groupeFound);
$this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ').$groupe);
}
$adherent->setGroupe($groupeFound);
} else {
$this->addWarning($row, $line, 'groupe', 'empty');
}
if (!empty($cotisations)) {
$cotisationArray = explode(',', $cotisations);
if (count($cotisationArray) > 0) {
foreach ($cotisationArray as $cotisationDetails) {
$cotisation = new Cotisation();
$now = new DateTime();
$cotisation->setReference('Import du '.$now->format('d/m/Y H:i'));
$cotisation->setOperateur($user);
$cotisation->setExpediteur($adherent);
$cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE);
$cotisationDetailsArray = explode(':', $cotisationDetails);
if (count($cotisationDetailsArray) == 1) {
$cotisation->setMontant(intval($cotisationDetails));
$cotisation->setDebut($now);
$cotisation->setFin(new DateTime('+ 1 year'));
} else {
$cotisation->setMontant(intval($cotisationDetailsArray[0]));
$cotisation->setAnnee(intval($cotisationDetailsArray[1]));
$cotisation->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101'));
$cotisation->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231'));
}
$user->addCotisation($cotisation);
// $this->em->persist($cotisation);
}
}
} else {
$this->addWarning($row, $line, 'cotisations', 'empty');
}
if (!empty($adresse) || !empty($cpostal) || !empty($ville)) {
$geolocFound = new Geoloc();
$geolocFound->setAdresse($adresse);
$geolocFound->setCpostal(intval($cpostal));
$geolocFound->setVille($ville);
$adherent->setGeoloc($geolocFound);
}
if (!$hasError) {
$this->addSuccess($row, $line, 'user', $this->translator->trans('Utilisateur bien ajouté : ').$user->__toString());
$this->userManager->updateUser($user);
$this->em->persist($user);
$this->em->flush();
$this->em->clear();
}
$line++;
}
ksort($this->errors);
ksort($this->warnings);
}
private function parseCSV($filePath, $fileName, $ignoreFirstLine = false)
{
$finder = new Finder();
$finder->files()
->in($filePath)
->name($fileName)
;
foreach ($finder as $file) { $csv = $file; }
// $finder = new Finder();
// $finder->files()
// ->in($filePath)
// ->name($fileName)
// ;
// foreach ($finder as $file) {
// $csv = $file;
// }
$csv = new \SplFileObject($filePath.'/'.$fileName);
$rows = array();
if (($handle = fopen($csv->getRealPath(), "r")) !== FALSE) {
$firstline = null;
if (($handle = fopen($csv->getRealPath(), "r")) !== false) {
$i = 0;
while (($data = fgetcsv($handle, null, ";")) !== FALSE) {
while (($data = fgetcsv($handle, null, ";")) !== false) {
$i++;
if ($ignoreFirstLine && $i == 1) { continue; }
if ($i == 1) {
$firstline = $data;
$rows[] = $data;
if ($ignoreFirstLine) {
continue;
}
} else {
if (count($firstline) != count($data)) {
$this->addError($data, $i, 'Ligne entière', $this->translator->trans("La ligne ne contient pas le bon nombre d'éléments requis !"));
continue;
}
$rows[] = array_combine(array_values($firstline), array_values($data));
}
}
fclose($handle);
}
return $rows;
}
private function addSuccess($row, $line, $key, $message = '')
{
$csvline = implode(';', array_values($row));
$this->success[$line][$key][$csvline] = $message;
}
private function addError($row, $line, $key, $err = '')
{
$this->lineErrors[$line] = implode(';', array_values($row));
$this->errors[$line][$key][$this->lineErrors[$line]] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$err.']';
}
private function addWarning($row, $line, $key, $err = '')
{
$csvline = implode(';', array_values($row));
if ($err == 'empty') {
$errString = $this->translator->trans('Valeur vide !');
$this->warnings[$line][$key][$csvline] ='['.$errString.' ]';
} else if ($err == 'invalid') {
$errString = $this->translator->trans('Valeur invalide !');
$this->warnings[$line][$key][$csvline] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$errString.']';
} else if ($err != '') {
$this->warnings[$line][$key][$csvline] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$err.']';
}
}
private function tofloat($num)
{
$dotPos = strrpos($num, '.');
$commaPos = strrpos($num, ',');
$sep = (($dotPos > $commaPos) && $dotPos) ? $dotPos :
((($commaPos > $dotPos) && $commaPos) ? $commaPos : false);
if (!$sep) {
return floatval(preg_replace("/[^0-9]/", "", $num));
}
return floatval(
preg_replace("/[^0-9]/", "", substr($num, 0, $sep)) . '.' .
preg_replace("/[^0-9]/", "", substr($num, $sep+1, strlen($num)))
);
}
}
......@@ -150,7 +150,7 @@ class IndexController extends AbstractController
$adherent = new Adherent();
$user = $this->userManager->createUser();
$groupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent');
$user->setEnabled(true);
$user->setEnabled(false);
$user->addGroup($groupe);
$user->addRole('ROLE_ADHERENT');
$adherent->setEcompte('0');
......@@ -158,7 +158,7 @@ class IndexController extends AbstractController
$adherent->setUser($user);
if (count($adherent->getUser()->getCotisations()) <= 0) {
$cotisation = new Cotisation();
$cotisation->setMontant($this->getParameter('cotisation_montant'));
$cotisation->setMontant(floatval($this->getParameter('app.cotisation_montant')));
$cotisation->setOperateur($adherent->getUser());
$cotisation->setExpediteur($adherent);
$cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE);
......@@ -174,8 +174,16 @@ class IndexController extends AbstractController
if ($form->isSubmitted()) {
if ($form->isValid()) {
$this->em->persist($adherent);
$this->em->persist($user);
$adherentNew = $form->getData();
$cotisationNew = $form['cotisation']->getData();
// dump($adherentNew);
// dump($cotisationNew);
// exit();
// $adherentNew->getUser()->removeCotisation($cotisation);
$this->em->persist($cotisationNew);
$adherentNew->getUser()->addCotisation($cotisationNew);
$this->em->persist($adherentNew);
$this->em->persist($adherentNew->getUser());
$this->em->flush();
$this->addFlash(
'success',
......
......@@ -11,6 +11,8 @@ use App\Entity\TransfertComptoirAdherent;
use App\Entity\TransfertComptoirPrestataire;
use App\Entity\TransfertPrestataireComptoir;
use App\Entity\Usergroup;
use App\Entity\VenteComptoirAdherent;
use App\Entity\VenteComptoirPrestataire;
use App\Form\Type\AdherentInfosFormType;
use App\Form\Type\AdhererFormType;
use App\Form\Type\GroupeInfosFormType;
......@@ -18,6 +20,8 @@ use App\Form\Type\TransactionAdherentPrestataireFormType;
use App\Form\Type\TransfertComptoirAdherentFormType;
use App\Form\Type\TransfertComptoirPrestataireFormType;
use App\Form\Type\TransfertPrestataireComptoirFormType;
use App\Form\Type\VenteComptoirAdherentFormType;
use App\Form\Type\VenteComptoirPrestataireFormType;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
......@@ -93,6 +97,42 @@ class UserComptoirController extends FluxController
}
/**
* @Route("/user/comptoir/vente/adherent/", name="venteComptoirAdherent")
* @IsGranted("ROLE_COMPTOIR")
*/
public function venteComptoirAdherentAction(Request $request)
{
$entity = new VenteComptoirAdherent();
$entity->setOperateur($this->getUser());
$form = $this->createForm(VenteComptoirAdherentFormType::class, $entity);
return $this->manageFluxForm(
$request,
$form,
$this->getUser()->getComptoirsgere()->getCompte(),
$this->translator->trans('Vente à un adhérent bien effectuée !'),
$this->translator->trans('Vente à un adhérent')
);
}
/**
* @Route("/user/comptoir/vente/prestataire/", name="venteComptoirPrestataire")
* @IsGranted("ROLE_COMPTOIR")
*/
public function venteComptoirPrestataireAction(Request $request)
{
$entity = new VenteComptoirPrestataire();
$entity->setOperateur($this->getUser());
$form = $this->createForm(VenteComptoirPrestataireFormType::class, $entity);
return $this->manageFluxForm(
$request,
$form,
$this->getUser()->getComptoirsgere()->getCompte(),
$this->translator->trans('Vente à un prestataire bien effectuée !'),
$this->translator->trans('Vente à un prestataire')
);
}
/**
* @Route("/user/comptoir/reconversion/", name="transfertPrestataireComptoir")
* @IsGranted("ROLE_COMPTOIR")
*/
......
......@@ -63,7 +63,7 @@ class CotisationInfos
public function __construct()
{
$now = new \DateTime();
$this->annee = $now->format('Y');
$this->annee = intval($now->format('Y'));
$this->debut = $now;
$this->fin = new \DateTime('+1 year');
$this->recu = false;
......
......@@ -15,12 +15,16 @@ use Symfony\Component\Validator\Constraints as Assert;
* @ORM\HasLifecycleCallbacks()
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"cotisation" = "Cotisation", "cotisation_adherent" = "CotisationAdherent", "cotisation_prestataire" = "CotisationPrestataire", "tro_adh_pre" = "TransactionAdherentPrestataire", "tro_adh_adh" = "TransactionAdherentAdherent", "tro_pre_adh" = "TransactionPrestataireAdherent", "tro_pre_pre" = "TransactionPrestatairePrestataire", "tre_cpt_adh" = "TransfertComptoirAdherent", "tre_cpt_grp" = "TransfertComptoirGroupe", "tre_cpt_pre" = "TransfertComptoirPrestataire", "tre_grp_cpt" = "TransfertGroupeComptoir", "tre_pre_cpt" = "TransfertPrestataireComptoir", "tre_pre_sie" = "TransfertPrestataireSiege", "tre_sie_grp" = "TransfertSiegeGroupe", "tre_grp_sie" = "TransfertGroupeSiege"})
* @ORM\DiscriminatorMap({"cotisation" = "Cotisation", "cotisation_adherent" = "CotisationAdherent", "cotisation_prestataire" = "CotisationPrestataire", "tro_adh_pre" = "TransactionAdherentPrestataire", "tro_adh_adh" = "TransactionAdherentAdherent", "tro_pre_adh" = "TransactionPrestataireAdherent", "tro_pre_pre" = "TransactionPrestatairePrestataire", "tre_cpt_adh" = "TransfertComptoirAdherent", "tre_cpt_grp" = "TransfertComptoirGroupe", "tre_cpt_pre" = "TransfertComptoirPrestataire", "tre_grp_cpt" = "TransfertGroupeComptoir", "tre_pre_cpt" = "TransfertPrestataireComptoir", "tre_pre_sie" = "TransfertPrestataireSiege", "tre_sie_grp" = "TransfertSiegeGroupe", "tre_grp_sie" = "TransfertGroupeSiege", "vte_cpt_pre" = "VenteComptoirPrestataire", "vte_cpt_adh" = "VenteComptoirAdherent"})
*/
abstract class Flux
{
use TimestampableEntity;
const TYPE_TRANSFERT = 'transfert';
const TYPE_TRANSACTION = 'transaction';
const TYPE_VENTE = 'vente';
/**
* @var int
*
......@@ -33,7 +37,6 @@ abstract class Flux
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="flux", cascade={"all"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
* @Assert\NotBlank
*/
protected $operateur;
......@@ -113,7 +116,7 @@ abstract class Flux
* @param User $destinataire
* @return $this
*/
public function setOperateur(User $operateur)
public function setOperateur(?User $operateur)
{
$this->operateur = $operateur;
return $this;
......@@ -235,6 +238,11 @@ abstract class Flux
return $this;
}
public function isVente()
{
return false;
}
/**
* @ORM\PostPersist
* @param LifecycleEventArgs $event
......@@ -258,12 +266,12 @@ abstract class Flux
} else {
$em = $event->getEntityManager();
$flux->getExpediteur()->setCompte($compteExp);
$em->persist($flux->getExpediteur());
if ($this->getParenttype() != 'vente') {
$compteDest = $flux->getDestinataire()->getCompte() + $flux->getMontant();
$flux->getDestinataire()->setCompte($compteDest);
$em->persist($flux->getExpediteur());
$em->persist($flux->getDestinataire());
}
$em->flush();
}
}
......
......@@ -37,7 +37,7 @@ class Import
/**
* @var User
*
* @ORM\ManyToOne(targetEntity="User", inversedBy="documents", cascade={"persist"})
* @ORM\ManyToOne(targetEntity="User", inversedBy="imports", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
*/
private $user;
......@@ -96,5 +96,4 @@ class Import
{
return 'Import du '.$this->getCreatedAt()?$this->getCreatedAt()->format('d/m/Y H:i'):'?';
}
}
......@@ -144,6 +144,7 @@ class Prestataire
* @var Groupe $groupe
*
* @ORM\ManyToOne(targetEntity="Groupe", inversedBy="prestataires")
* @Assert\NotBlank
*/
private $groupe;
......
......@@ -29,6 +29,6 @@ abstract class Transaction extends Flux
*/
public function getParenttype(): string
{
return 'transaction';
return self::TYPE_TRANSACTION;
}
}
......@@ -32,6 +32,6 @@ abstract class Transfert extends Flux
*/
public function getParenttype(): string
{
return 'transfert';
return self::TYPE_TRANSFERT;
}
}
......@@ -31,4 +31,9 @@ class TransfertComptoirAdherent extends Transfert
{
return 'comptoir_adherent';
}
public function isVente()
{
return false;
}
}
......@@ -6,7 +6,7 @@ use Doctrine\ORM\Mapping as ORM;
/**
* TRANSFERT
* - COMPTOIRS => PRESTATAIRES (Diffusion de monnaie papier auprès des prestataires)
* - COMPTOIRS => PRESTATAIRES (Transfert de monnaie virtuelle auprès des prestataires)
*
* @ORM\Entity()
*/
......
......@@ -68,6 +68,13 @@ class User extends BaseUser
private $faqs;
/**
* @var ArrayCollection|Import[]
*
* @ORM\OneToMany(targetEntity="Import", mappedBy="user", cascade={"persist"})
*/
private $imports;
/**
* @ORM\OneToMany(targetEntity="Flux", mappedBy="operateur", cascade={"persist"})
* @ORM\OrderBy({"createdAt" = "DESC"})
*/
......@@ -277,9 +284,9 @@ class User extends BaseUser
*/
public function addCotisation($cotisation)
{
if (!$this->cotisations->contains($cotisation)) {
$this->flux[] = $cotisation;
if (!$this->flux->contains($cotisation)) {
$cotisation->setOperateur($this);
$this->flux->add($cotisation);
}
return $this;
}
......
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Vente => (Diffusion de monnaie papier auprès des adhérents)
*
* Types de vente :
*
* - COMPTOIR => ADHERENTS (Vente à un adherent)
* - COMPTOIR => PRESTATAIRES (Vente à un prestataire)
*
* @ORM\Entity
*/
abstract class Vente extends Flux
{
/**
* @return string
*/
public function getParenttype(): string
{
return self::TYPE_VENTE;
}
}
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* VENTE
* - COMPTOIRS => ADHERENTS (Diffusion de monnaie papier auprès des adhérents)
*
* @ORM\Entity()
*/
class VenteComptoirAdherent extends Vente
{
/**
* @ORM\OneToOne(targetEntity="Comptoir")
* @ORM\JoinColumn(name="comptoir_id", referencedColumnName="id", nullable=true)
*/
protected $expediteur;
/**
* @ORM\OneToOne(targetEntity="Adherent")
* @ORM\JoinColumn(name="adherent_id", referencedColumnName="id", nullable=true)
*/
protected $destinataire;
/**
* @return string
*/
public function getType(): string
{
return 'comptoir_adherent';
}
}
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* VENTE
* - COMPTOIRS => PRESTATAIRES (Diffusion de monnaie papier auprès des prestataires)
*
* @ORM\Entity()
*/
class VenteComptoirPrestataire extends Vente
{
/**
* @ORM\OneToOne(targetEntity="Comptoir")
* @ORM\JoinColumn(name="comptoir_id", referencedColumnName="id", nullable=true)
*/
protected $expediteur;
/**
* @ORM\OneToOne(targetEntity="Prestataire")
* @ORM\JoinColumn(name="prestataire_id", referencedColumnName="id", nullable=true)
*/
protected $destinataire;
/**
* @return string
*/
public function getType(): string
{
return 'comptoir_prestataire';
}
}
......@@ -12,6 +12,7 @@ abstract class MoyenEnum
const MOYEN_HELLOASSO = "helloasso";
const MOYEN_MLC = "mlc";
const MOYEN_AUTRE = "autre";
const MOYEN_VENTE = "vente";
/** @var array user friendly named type */
......@@ -24,6 +25,7 @@ abstract class MoyenEnum
self::MOYEN_HELLOASSO => 'HelloAsso',
self::MOYEN_MLC => 'MLC',
self::MOYEN_AUTRE => 'Autre',
self::MOYEN_VENTE => 'Vente',
];
/**
......@@ -52,7 +54,8 @@ abstract class MoyenEnum
self::MOYEN_TRANSFERT,
self::MOYEN_HELLOASSO,
self::MOYEN_MLC,
self::MOYEN_AUTRE
self::MOYEN_AUTRE,
self::MOYEN_VENTE
];
}
}
......@@ -210,6 +210,21 @@ class FormFactory
return $form->createView();
}
public function getVenteComptoirToXForm(User $user, $type)
{
$type = strtolower($type);
if (empty($user) || empty($user->getComptoirsgere()) || !($type == 'adherent' || $type == 'groupe' || $type == 'prestataire')) {
throw new \Exception("[FORM 12] Opération impossible !");
}
$class = "App\Entity\VenteComptoir".ucwords($type);
$entity = new $class();
$entity->setOperateur($user);
$entity->setExpediteur($user->getComptoirsgere());
$form = $this->ff->create('App\Form\Type\VenteComptoir'.ucwords($type).'FormType', $entity, array('action' => $this->router->generate('venteComptoir'.ucwords($type))));
return $form->createView();
}
public function getTransfertComptoirGroupeForm(User $user)
{
if (empty($user) || empty($user->getGroupesgere())) {
......
<?php
namespace App\Form\Extension;
use Sonata\MediaBundle\Form\Type\MediaType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class MediaTypeExtension extends AbstractTypeExtension
{
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefined(['show_unlink' => true]);
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
if (!isset($options['show_unlink'])) {
$builder->add('unlink', HiddenType::class, array(
'mapped' => false,
'data' => false,
'required' => false,
));
}
}
/**
* Return the class of the type being extended.
*/
public static function getExtendedTypes(): iterable
{
// return FormType::class to modify (nearly) every field in the system
return [MediaType::class];
}
}
\ No newline at end of file
......@@ -34,7 +34,7 @@ class AddCotisationFormType extends AbstractType
// dump($flux);
// exit();
if (empty($this->security) && !empty($this->security->getUser())) {
throw new \Exception("Opération impossible ! Utilisateur déjà connecté !");
throw new \Exception("Opération impossible ! Utilisateur non connecté !");
}
$builder
->add('type', HiddenType::class, array(
......@@ -43,7 +43,9 @@ class AddCotisationFormType extends AbstractType
))
->add('operateur', HiddenType::class, array(
'entity_class' => User::class,
'em' => $this->em
'em' => $this->em,
'data_class' => null,
'data' => $this->security->getUser()
))
->add('reference', HiddenType::class, array(
'label' => 'Reference :',
......
......@@ -59,12 +59,12 @@ class AdhererFormType extends AbstractType
'label' => 'ADRESSE',
'required' => false
))
// ->add('cotisation', AddCotisationFormType::class, array(
// 'label' => false,
// 'required' => false,
// 'mapped' => false,
// 'data' => $adherent->getUser()->getCotisations()->first()
// ))
->add('cotisation', AddCotisationFormType::class, array(
'label' => false,
'required' => false,
'mapped' => false,
'data' => $adherent->getUser()->getCotisations()->last()
))
->add('save', SubmitType::class, ['label' => "Valider l'adhésion"])
;
}
......
......@@ -25,7 +25,7 @@ class CotisationFormType extends FluxFormType
))
->add('montant', MoneyType::class, array(
'label' => 'Montant',
'data' => $this->container->getParameter('cotisation_montant')
'data' => floatval($this->container->getParameter('app.cotisation_montant'))
))
->add('moyen', ChoiceType::class, array(
'required' => true,
......
......@@ -7,6 +7,7 @@ use App\Entity\User;
use App\Enum\MoyenEnum;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
......@@ -25,11 +26,13 @@ class FluxFormType extends AbstractType
{
protected $em;
protected $security;
protected $container;
public function __construct(EntityManagerInterface $em, Security $security)
public function __construct(EntityManagerInterface $em, Security $security, ContainerInterface $container)
{
$this->em = $em;
$this->security = $security;
$this->container = $container;
}
public function buildForm(FormBuilderInterface $builder, array $options)
......
......@@ -3,26 +3,45 @@
namespace App\Form\Type;
use App\Entity\Import;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Sonata\MediaBundle\Form\Type\MediaType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;
class ImportFormType extends AbstractType
{
protected $em;
protected $security;
public function __construct(EntityManagerInterface $em, Security $security)
{
$this->em = $em;
$this->security = $security;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
if (empty($this->security) && !empty($this->security->getUser())) {
throw new \Exception("Opération impossible ! Utilisateur non connecté !");
}
$builder
->add('media', MediaType::class, array(
'provider' => 'sonata.media.provider.file',
'context' => 'import',
'label' => 'Fichier (.csv)'
'label' => 'Fichier .csv',
// 'show_unlink' => false
))
->add('user', HiddenType::class, array(
'label' => false
'data_class' => null,
'data' => $this->security->getUser()->getId(),
'entity_class' => User::class,
'em' => $this->em
))
->add('save', SubmitType::class, ['label' => "Importer les données"])
;
......
......@@ -23,7 +23,7 @@ class TransfertComptoirAdherentFormType extends TransfertFormType
))
->add('destinataire', EntityType::class, array(
'class' => Adherent::class,
// 'choices' => $this->em->getRepository(Adherent::class)->findOrderByName(),
'choices' => $this->em->getRepository(Adherent::class)->findOrderByName(),
'placeholder' => 'Adherent',
'required' => true,
'label' => 'Adherent :',
......
<?php
namespace App\Form\Type;
use App\Entity\Adherent;
use App\Entity\Comptoir;
use App\Entity\VenteComptoirAdherent;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class VenteComptoirAdherentFormType extends VenteFormType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('expediteur', HiddenType::class, array(
'data' => $this->security->getUser()->getComptoirsgere()->getId(),
'data_class' => null,
'entity_class' => Comptoir::class,
'em' => $this->em
))
->add('destinataire', EntityType::class, array(
'class' => Adherent::class,
'choices' => $this->em->getRepository(Adherent::class)->findOrderByName(),
'placeholder' => 'Adherent',
'required' => true,
'label' => 'Adherent :',
))
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'class' => VenteComptoirAdherent::class,
));
}
public function getParent()
{
return VenteFormType::class;
}
public function getBlockPrefix()
{
return 'formVenteComptoirAdherent';
}
}
<?php
namespace App\Form\Type;
use App\Entity\Comptoir;
use App\Entity\Prestataire;
use App\Entity\VenteComptoirPrestataire;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class VenteComptoirPrestataireFormType extends VenteFormType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('expediteur', HiddenType::class, array(
'data' => $this->security->getUser()->getComptoirsgere()->getId(),
'data_class' => null,
'entity_class' => Comptoir::class,
'em' => $this->em
))
->add('destinataire', EntityType::class, array(
'class' => Prestataire::class,
'choices' => $this->em->getRepository(Prestataire::class)->findBy(array('enabled' => true), array('raison'=> 'ASC')),
'placeholder' => 'Prestataire',
'required' => true,
'label' => 'Prestataire :',
))
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'class' => VenteComptoirPrestataire::class,
));
}
public function getParent()
{
return VenteFormType::class;
}
public function getBlockPrefix()
{
return 'formVenteComptoirPrestataire';
}
}
<?php
namespace App\Form\Type;
use App\Enum\MoyenEnum;
use App\Form\Type\FluxFormType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
class VenteFormType extends FluxFormType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', HiddenType::class, array(
'data' => 'transfert',
'data_class' => null
))
->add('moyen', HiddenType::class, array(
'data' => MoyenEnum::MOYEN_VENTE
))
;
}
public function getParent()
{
return FluxFormType::class;
}
public function getBlockPrefix()
{
return 'formVente';
}
}
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20190312005614 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('CREATE TABLE import (id INT AUTO_INCREMENT NOT NULL, media_id INT DEFAULT NULL, user_id INT DEFAULT NULL, enabled TINYINT(1) NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX IDX_9D4ECE1DEA9FDD75 (media_id), INDEX IDX_9D4ECE1DA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB');
$this->addSql('ALTER TABLE import ADD CONSTRAINT FK_9D4ECE1DEA9FDD75 FOREIGN KEY (media_id) REFERENCES media__media (id)');
$this->addSql('ALTER TABLE import ADD CONSTRAINT FK_9D4ECE1DA76ED395 FOREIGN KEY (user_id) REFERENCES user (id)');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('DROP TABLE import');
}
}
......@@ -37,6 +37,7 @@ class FormExtension extends AbstractExtension
new \Twig_SimpleFunction('getTransfertPrestataireSiegeForm', array($this, 'getTransfertPrestataireSiegeForm')),
new \Twig_SimpleFunction('getTransfertPrestataireComptoirForm', array($this, 'getTransfertPrestataireComptoirForm')),
new \Twig_SimpleFunction('getTransfertComptoirToXForm', array($this, 'getTransfertComptoirToXForm')),
new \Twig_SimpleFunction('getVenteComptoirToXForm', array($this, 'getVenteComptoirToXForm')),
new \Twig_SimpleFunction('getTransfertComptoirGroupeForm', array($this, 'getTransfertComptoirGroupeForm')),
new \Twig_SimpleFunction('getTransfertGroupeComptoirForm', array($this, 'getTransfertGroupeComptoirForm')),
new \Twig_SimpleFunction('getTransfertSiegeGroupeForm', array($this, 'getTransfertSiegeGroupeForm')),
......@@ -100,6 +101,10 @@ class FormExtension extends AbstractExtension
{
return $this->container->get('app.formfactory')->getTransfertComptoirToXForm($user, $destinataire);
}
public function getVenteComptoirToXForm(User $user, $destinataire)
{
return $this->container->get('app.formfactory')->getVenteComptoirToXForm($user, $destinataire);
}
public function getTransfertComptoirGroupeForm(User $user)
{
return $this->container->get('app.formfactory')->getTransfertComptoirGroupeForm($user);
......
<div class="card mb-3 {% if app.user.adherent.ecompte > 0 %}border-success{% else %}border-error{% endif %}">
<div class="card-header"><i class="fa fa-coins mr-4"></i> {{ 'Solde de mon compte'|trans }} : <b>{{app.user.adherent.ecompte}}</b></div>
<div class="card-header"><i class="fa fa-coins mr-4"></i> {{ 'Solde de mon e-compte'|trans }} : <b>{{app.user.adherent.ecompte}}</b></div>
</div>
\ No newline at end of file
{% extends base_template %}
{% import _self as macros %}
{% block actions %}
{% endblock %}
{% block breadcrumb %}{% endblock %}
......@@ -19,11 +21,57 @@
{% endblock %}
{% block content %}
<div class="col-xs-12 col-md-12 p-4">
<div class="p-4">
<h4><u>{{ "Exemples d'importations possible (Fichiers .csv uniquement):"|trans }}</u></h4>
<div class='mb-5'>
{% for key, csvparam in csvparams %}
<h5><strong>{{ key|capitalize }} : </strong><a class='ml-4' target='_blank' href='{{ csvparam.file }}'>Télécharger un exemple</a></h5>
<p class='ml-4'><i>{{ csvparam.header }}</i></p>
<p class='ml-4 mb-4'><i>{{ 'Exemple'|trans }} :</i> {{ csvparam.example }}</p>
{% endfor %}
</div>
{{form_start(form)}}
{{ form_row(form.media) }}
{{ form_row(form.user) }}
{{ form_row(form.save) }}
{{form_end(form)}}
{% if errors is defined and errors|length > 0 %}
<div class='container bg-danger w-100 py-4 row'>
{% if errors['error'] is defined %}
{{ errors['error'] }}
{% else %}
{{ macros.show_error(errors) }}
{% endif %}
</div>
{% endif %}
{% if warnings is defined and warnings|length > 0 %}
<div class='container bg-warning w-100 py-4 row'>
{{ macros.show_error(warnings) }}
</div>
{% endif %}
{% if success is defined and success|length > 0 %}
<div class='container bg-success w-100 py-4 row'>
{{ macros.show_error(success) }}
</div>
{% endif %}
{% if linkcsverror is defined and linkcsverror != null %}
<div class='py-4'>
<a href='{{ linkcsverror }}' role="button" class="btn-primary btn">{{ 'Télécharger CSV avec lignes en erreurs'|trans }}</a>
</div>
{% endif %}
</div>
{% endblock %}
{% macro show_error(errors) %}
{% for line, errorA in errors %}
<div class='col-12'>
<span>Ligne {{line}}</span>
{% for key, errorB in errorA %}
{% for csvline, errorString in errorB %}
<span class="pl-2">{% if (key is not empty) %}[{{key}}]{% endif %}{{errorString}}</span>
{% endfor %}
{% endfor %}
</div>
{% endfor %}
{% endmacro %}
\ No newline at end of file
......@@ -109,7 +109,8 @@
{% include 'block/userinfos.html.twig' %}
{% include 'block/userpassword.html.twig' %}
{% include 'block/transactions.html.twig' %}
{% include 'comptoir/block/transaction_adherent.html.twig' %}
{% include 'comptoir/block/vente_adherent.html.twig' %}
{% include 'comptoir/block/vente_prestataire.html.twig' %}
{% include 'comptoir/block/transaction_prestataire.html.twig' %}
{% include 'comptoir/block/reconversion.html.twig' %}
......
......@@ -25,7 +25,7 @@ Modified for MLC from Sonata package.
{% block meta_tags %}
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="UTF-8">
<link rel="shortcut icon" href="{{parameter('favicon_url')}}" type="image/x-icon" />
<link rel="shortcut icon" href="{{parameter('app.favicon_url')}}" type="image/x-icon" />
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
{% endblock %}
......
{#
This file is part of the Sonata package.
(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% block user_block %}
{% if app.user %}
{% set _bg_class = "bg-light-blue" %}
{% set _logout_uri = url('fos_user_security_logout') %}
{# SEUL CHANGEMENT POUR LA MONNAIE LOCALE CI DESSOUS : #}
{% set _logout_text = 'user_block_logout'|trans({}, 'SonataUserBundle') %}
{% set _profile_uri = sonata_user.userAdmin.isGranted('EDIT', app.user) ? sonata_user.userAdmin.generateUrl('edit', {id: app.user.id}) : sonata_user.userAdmin.generateUrl('show', {id: app.user.id}) %}
{% set _profile_text = 'user_block_profile'|trans({}, 'SonataUserBundle') %}
{% set _user_image = sonata_user.defaultAvatar ? asset(sonata_user.defaultAvatar) : null %}
{# Customize this with your profile picture implementation, see below for example #}
{#{% set _user_image = app.user.profilePicture|default(asset(sonata_user.defaultAvatar)) %}#}
{% if is_granted('ROLE_PREVIOUS_ADMIN') and sonata_user.impersonating %}
{% set _bg_class = "bg-light-green" %}
{% set _logout_uri = url(sonata_user.impersonating.route, sonata_user.impersonating.parameters| merge({'_switch_user': '_exit'})) %}
{% set _logout_text = 'switch_user_exit'|trans({}, 'SonataUserBundle') %}
{% endif %}
<li class="user-header {{ _bg_class }}">
{% if _user_image %}
<img src="{{ _user_image }}" class="img-circle" alt="Avatar" />
{% endif %}
<p>{{ app.user }}</p>
</li>
{#
Uncomment to add some information
<li class="user-body">
</li>
#}
<li class="user-footer">
<div class="pull-left">
<a href="{{ _profile_uri }}" class="btn btn-default btn-flat"><i class="fa fa-user"></i> {{ _profile_text }}</a>
</div>
<div class="pull-right">
<a href="{{ _logout_uri }}" class="btn btn-default btn-flat"><i class="fa fa-sign-out fa-fw"></i> {{ _logout_text }}</a>
</div>
</li>
{% endif %}
{% endblock %}
......@@ -8,13 +8,13 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>{{title|default(parameter('mlc_title')) }}</title>
<title>{{title|default(parameter('app.mlc_title')) }}</title>
<meta name="description" content="{{ description|default('mlc_description'|trans) }}" />
<meta name="keywords" content="{{ keywords|default('mlc_keywords'|trans) }}" />
<meta name="author" content="{{ 'mlc_author'|trans }}">
{# FAVICON #}
<link rel="shortcut icon" href="{{parameter('favicon_url')}}" type="image/x-icon" />
<link rel="shortcut icon" href="{{parameter('app.favicon_url')}}" type="image/x-icon" />
{# UTILISER LES FONT AWESOME POUR L'ICONOGRAPHIE #}
<link rel="stylesheet" href="/fontawesome/css/all.min.css">
{# UTILISER LEAFLET POUR LA CARTE #}
......
......@@ -6,7 +6,7 @@
<nav class="menu navbar navbar-expand-md navbar-light bg-light">
<a class="navbar-brand" href="{{ url('index') }}">
<img src="/images/logo.png" height="45" class="d-inline-block align-top" alt="{{ parameter('mlc_name') }}">
<img src="/images/logo.png" height="45" class="d-inline-block align-top" alt="{{ parameter('app.mlc_name') }}">
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
......
......@@ -3,13 +3,13 @@
$(function () {
$('[data-toggle="tooltip"]').tooltip()
if ($('#{{idmap}}').length) {
var mymap = L.map('{{idmap}}').setView({{parameter('map_center')}}, {{parameter('map_zoom')}});
var mymap = L.map('{{idmap}}').setView({{parameter('app.map_center')}}, {{parameter('app.map_zoom')}});
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox.streets',
accessToken: '{{parameter('map_token')}}'
accessToken: '{{parameter('app.map_token')}}'
}).addTo(mymap);
{# AJOUTER LES MARQUEURS SUR LA CARTE #}
......
{% extends 'block/onetransaction.html.twig' %}
{% block blocktitle %}
<i class="fa fa-exchange-alt mr-4"></i> {{ 'Vente à un adhérent'|trans }}
<i class="fa fa-exchange-alt mr-4"></i> {{ 'Transfert à un adhérent'|trans }}
{% endblock blocktitle %}
{% block blockcontent %}
{% set form = getTransfertComptoirToXForm(app.user, 'adherent') %}
......
{% extends 'block/onetransaction.html.twig' %}
{% block blocktitle %}
<i class="fa fa-exchange-alt mr-4"></i> {{ 'Vente à un prestataire'|trans }}
<i class="fa fa-exchange-alt mr-4"></i> {{ 'Transfert à un prestataire'|trans }}
{% endblock blocktitle %}
{% block blockcontent %}
{% set form = getTransfertComptoirToXForm(app.user, 'prestataire') %}
......
{% extends 'block/onetransaction.html.twig' %}
{% block blocktitle %}
<i class="fa fa-exchange-alt mr-4"></i> {{ 'Vente à un adhérent'|trans }}
{% endblock blocktitle %}
{% block blockcontent %}
{% set form = getVenteComptoirToXForm(app.user, 'adherent') %}
{{ parent() }}
{% endblock blockcontent %}
\ No newline at end of file
{% extends 'block/onetransaction.html.twig' %}
{% block blocktitle %}
<i class="fa fa-exchange-alt mr-4"></i> {{ 'Vente à un prestataire'|trans }}
{% endblock blocktitle %}
{% block blockcontent %}
{% set form = getVenteComptoirToXForm(app.user, 'prestataire') %}
{{ parent() }}
{% endblock blockcontent %}
\ No newline at end of file
......@@ -3,13 +3,13 @@
$(function () {
$('[data-toggle="tooltip"]').tooltip()
if ($('#{{idmap}}').length) {
var mymap = L.map('{{idmap}}').setView({{parameter('map_center')}}, {{parameter('map_zoom')}});
var mymap = L.map('{{idmap}}').setView({{parameter('app.map_center')}}, {{parameter('app.map_zoom')}});
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox.streets',
accessToken: '{{parameter('map_token')}}'
accessToken: '{{parameter('app.map_token')}}'
}).addTo(mymap);
{# AJOUTER LES MARQUEURS SUR LA CARTE #}
......
{% extends '@SonataAdmin/CRUD/base_edit.html.twig' %}
{#
{% block form %}
<a href="{{path('cotisation_prestataire_list', {'filter': {'expediteur': {'value': admin.id(object) }}}) }}">{{ 'Voir les cotisations'}}</a>
{{ block('parentForm') }}
{% endblock %}
http://www.doume.test/admin/cotisation_prestataire/list?filter%5BcotisationInfos__annee%5D%5Btype%5D=&filter%5BcotisationInfos__annee%5D%5Bvalue%5D=&filter%5Bmontant%5D%5Btype%5D=&filter%5Bmontant%5D%5Bvalue%5D=&filter%5BcotisationInfos__recu%5D%5Btype%5D=&filter%5BcotisationInfos__recu%5D%5Bvalue%5D=&filter%5Bexpediteur%5D%5Btype%5D=&filter%5Bexpediteur%5D%5Bvalue%5D=19&filter%5B_page%5D=1&filter%5B_sort_by%5D=createdAt&filter%5B_sort_order%5D=DESC&filter%5B_per_page%5D=32 #}
......@@ -3,13 +3,13 @@
$(function () {
$('[data-toggle="tooltip"]').tooltip()
if ($('#{{idmap}}').length) {
var mymap = L.map('{{idmap}}').setView({{parameter('map_center')}}, {{parameter('map_zoom')}});
var mymap = L.map('{{idmap}}').setView({{parameter('app.map_center')}}, {{parameter('app.map_zoom')}});
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox.streets',
accessToken: '{{parameter('map_token')}}'
accessToken: '{{parameter('app.map_token')}}'
}).addTo(mymap);
{# AJOUTER LES MARQUEURS SUR LA CARTE #}
......
......@@ -63,6 +63,10 @@ class ApplicationAvailabilityFunctionalTest extends WebTestCase
yield ['/admin/prestataire/create'];
yield ['/admin/cotisation_prestataire/list'];
yield ['/admin/cotisation_prestataire/create'];
yield ['/admin/prestataire/19/edit'];
yield ['/admin/app/user/51/edit'];
yield ['/admin/adherent/1/edit'];
yield ['/admin/app/user/2/edit'];
yield ['/admin/app/groupeprestataire/list'];
yield ['/admin/app/groupeprestataire/create'];
yield ['/admin/app/groupe/list'];
......@@ -88,7 +92,5 @@ class ApplicationAvailabilityFunctionalTest extends WebTestCase
yield ['/admin/app/transfertprestatairesiege/list'];
yield ['/admin/sonata/menu/list'];
yield ['/admin/sonata/menu/create'];
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment