Commit 5659b01b by Julien Jorry

Import : Amélioration et modification de l'import => migrate BDD + composer install

parent aae553d4
...@@ -66,11 +66,11 @@ ...@@ -66,11 +66,11 @@
"symfony/webpack-encore-bundle": "^1.7", "symfony/webpack-encore-bundle": "^1.7",
"symfony/yaml": "4.4.*", "symfony/yaml": "4.4.*",
"vich/uploader-bundle": "^1.8", "vich/uploader-bundle": "^1.8",
"willdurand/geocoder-bundle": "^5.0" "willdurand/geocoder-bundle": "^5.0",
"doctrine/doctrine-fixtures-bundle": "^3.0",
"hautelook/alice-bundle": "^2.3"
}, },
"require-dev": { "require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0",
"hautelook/alice-bundle": "^2.3",
"sensiolabs/security-checker": "^5.0", "sensiolabs/security-checker": "^5.0",
"symfony/browser-kit": "4.4.*", "symfony/browser-kit": "4.4.*",
"symfony/css-selector": "4.4.*", "symfony/css-selector": "4.4.*",
......
...@@ -29,10 +29,10 @@ return [ ...@@ -29,10 +29,10 @@ return [
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true], Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true],
Knp\Bundle\PaginatorBundle\KnpPaginatorBundle::class => ['all' => true], Knp\Bundle\PaginatorBundle\KnpPaginatorBundle::class => ['all' => true],
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true], Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true],
Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => ['dev' => true, 'test' => true], Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => ['all' => true],
Fidry\AliceDataFixtures\Bridge\Symfony\FidryAliceDataFixturesBundle::class => ['dev' => true, 'test' => true], Fidry\AliceDataFixtures\Bridge\Symfony\FidryAliceDataFixturesBundle::class => ['all' => true],
Hautelook\AliceBundle\HautelookAliceBundle::class => ['dev' => true, 'test' => true], Hautelook\AliceBundle\HautelookAliceBundle::class => ['all' => true],
JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true], JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true],
Sonata\MediaBundle\SonataMediaBundle::class => ['all' => true], Sonata\MediaBundle\SonataMediaBundle::class => ['all' => true],
App\Application\Sonata\MediaBundle\ApplicationSonataMediaBundle::class => ['all' => true], App\Application\Sonata\MediaBundle\ApplicationSonataMediaBundle::class => ['all' => true],
......
sonata_doctrine_orm_admin:
templates:
types:
show: # or "list"
json: '@SonataAdmin/show_json.html.twig'
sonata_admin: sonata_admin:
security: security:
# handler: sonata.admin.security.handler.role # handler: sonata.admin.security.handler.role
......
...@@ -14,21 +14,29 @@ parameters: ...@@ -14,21 +14,29 @@ parameters:
app.import.separator: ';' app.import.separator: ';'
app.import.header: app.import.header:
groupe: groupe:
header: 'name;content;compte' header: 'nom;description;compte'
example: 'Groupe local n°1;<b>Groupe local n°1</b>;123' example: 'Groupe local n°1;<b>Groupe local n°1</b>;123'
file: '/csv/groupe.csv' filecsv: '/csv/groupe.csv'
filexls: '/csv/groupe.xlsx'
filenum: '/csv/groupe.numbers'
comptoir: comptoir:
header: 'groupe;name;content;phone;adresse;cpostal;ville;compte' header: 'groupe;nom;description;adresse;cpostal;ville;latitude;longitude;compte;contact1;phone1;email1;contact2;phone2;email2;contact3;phone3;email3'
example: 'Comptoir n°1;Comptoir n°1;<b>Comptoir n°1</b>;0123456789;2, rue charles de gaulle;12345;Paris;123,45' example: 'Groupe local n°1;Comptoir n°1;<b>Comptoir n°1</b>;2, rue charles de gaulle;12345;Paris;45,12345;3,12345;123;M. Jean Dupont;0612345678;jean.dupont@email.com;Contact comptoir;0198765432;contact.comptoir@email.com;Contact 3;0198765432;contact.comptoir2@email.com'
file: '/csv/comptoir.csv' filecsv: '/csv/comptoir.csv'
filexls: '/csv/comptoir.xlsx'
filenum: '/csv/comptoir.numbers'
adherent: adherent:
header: 'groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte;cotisations' 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"' 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' filecsv: '/csv/adherent.csv'
filexls: '/csv/adherent.xlsx'
filenum: '/csv/adherent.numbers'
prestataire: prestataire:
header: 'groupe;adresse;cpostal;ville;raison;metier;statut;responsable;iban;siret;web;compte;horaires;description;firstname;lastname;email;phone;mobile;rubriques;cotisations' header: 'groupe;adresse;cpostal;ville;raison;ecompte;metier;statut;responsable;iban;siret;web;horaires;description;rubriques;tags;tauxreconversion;contact1;phone1;email1;contact2;phone2;email2;contact3;phone3;email3'
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"' example: 'Groupe local n°1;2, rue Charles de gaulle;12345;Paris;Nom du prestataire;123,45;Directeur;SARL;Jean Dupont;FR7630001007941234567890185;732 829 320 00074;www.siteweb.com;Dimanche de 8h à 12h;<b>Description du prestataire</b>;Amap,Fruits,Légumes,Marchés;tag1,tag2;2;M. Jean Dupont;0123456789;jean.dupont@email.com;Contact comptoir;0698765432;contact.comptoir@email.com;Contact 3;0198765432;contact.comptoir2@email.com'
file: '/csv/prestataire.csv' filecsv: '/csv/prestataire.csv'
filexls: '/csv/prestataire.xlsx'
filenum: '/csv/prestataire.numbers'
# SERVICES # SERVICES
services: services:
...@@ -411,7 +419,7 @@ services: ...@@ -411,7 +419,7 @@ services:
admin.import: admin.import:
class: App\Admin\ImportAdmin class: App\Admin\ImportAdmin
arguments: [~, ~, App\Controller\ImportController] arguments: [~, App\Entity\Import, App\Controller\ImportController]
tags: tags:
- name: sonata.admin - name: sonata.admin
manager_type: orm manager_type: orm
......
...@@ -2,20 +2,20 @@ ...@@ -2,20 +2,20 @@
"entrypoints": { "entrypoints": {
"app": { "app": {
"js": [ "js": [
"/build/runtime.js", "/build/runtime.420770e4.js",
"/build/app.js" "/build/app.a6090119.js"
], ],
"css": [ "css": [
"/build/app.css" "/build/app.b1a10d11.css"
] ]
}, },
"admin": { "admin": {
"js": [ "js": [
"/build/runtime.js", "/build/runtime.420770e4.js",
"/build/admin.js" "/build/admin.da628ab6.js"
], ],
"css": [ "css": [
"/build/admin.css" "/build/admin.b8c3eca8.css"
] ]
} }
} }
......
{ {
"build/admin.css": "/build/admin.css", "build/admin.css": "/build/admin.b8c3eca8.css",
"build/admin.js": "/build/admin.js", "build/admin.js": "/build/admin.da628ab6.js",
"build/app.css": "/build/app.css", "build/app.css": "/build/app.b1a10d11.css",
"build/app.js": "/build/app.js", "build/app.js": "/build/app.a6090119.js",
"build/runtime.js": "/build/runtime.js", "build/runtime.js": "/build/runtime.420770e4.js",
"build/ckeditor/adapters/jquery.js": "/build/ckeditor/adapters/jquery.js", "build/ckeditor/adapters/jquery.js": "/build/ckeditor/adapters/jquery.js",
"build/ckeditor/ckeditor.js": "/build/ckeditor/ckeditor.js", "build/ckeditor/ckeditor.js": "/build/ckeditor/ckeditor.js",
"build/ckeditor/config.js": "/build/ckeditor/config.js", "build/ckeditor/config.js": "/build/ckeditor/config.js",
......
groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte;cotisations groupe;email;prenom;nom;phone;mobile;adresse;cpostal;ville;ecompte;cotisations
Nom du groupe local;Prénom;Nom de famille;Courriel / Email valide;Numéro de téléphone fixe;Numéro de téléphone mobile;Adresse complète;Code postal;Nom de la ville;Compte numérique (non obligatoire);Cotisations (montant:année,montant:année... => exemple : 10:2017,10,2018,10:2019) Groupe local n°1;jean.dupont@gmail.com;Jean;Dupont;13456789;612345678;2, rue Charles de gaulle;12345;Paris;123;10:2017,10:2018,10:2019
"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" \ No newline at end of file
\ No newline at end of file
groupe;name;content;phone;mobile;adresse;cpostal;ville;compte groupe;nom;description;adresse;cpostal;ville;latitude;longitude;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;contact1;phone1;email1;contact2;phone2;email2
Nom du groupe local;Nom du comptoir;Description du comptoir (html);Téléphone fixe du comptoir;Téléphone mobile du comptoir;Adresse complète;Code postal;Nom de la ville;Compte du comtoir en monnaie locale Groupe local n°1;Comptoir n°1;<b>Comptoir n°1</b>;2, rue charles de gaulle;12345;Paris;45,12345;3,12345;123;john.doe@email.com;Doe;John;0123456789;0623456789;M. Jean Dupont;0123456789;jean.dupont@email.com;Contact comptoir;0198765432;contact.comptoir@email.com
Groupe local n°1;Comptoir n°1;<b>Comptoir n°1</b>;123,45;0123456789;0612345678;2, rue charles de gaulle;12345;Paris;123,45 Groupe local n°1;;;2, rue charles de gaulle;;Paris;45,12345;3,12345;123;john.doe@email.com;Doe;John;0123456789;0623456789;M. Jean Dupont;0123456789;jean.dupont@email.com;Contact comptoir;0198765432;contact.comptoir@email.com
\ No newline at end of file \ No newline at end of file
name;content;compte nom;description;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1
Nom du groupe local;Description du groupe (html);Compte de billet MLC Groupe local n°1;<b>Groupe local n°1</b>;123;john.doe@email.com;Doe;John;0123456789;0623456789
Groupe local n°1;<b>Groupe local n°1</b>;123 \ No newline at end of file
\ 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;adresse;cpostal;ville;raison;ecompte;metier;statut;responsable;iban;siret;web;horaires;description;rubriques;tags;tauxreconversion;cotisations;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;contact1;phone1;email1;contact2;phone2;email2
Nom du groupe local;Adresse complète;Code postal;Nom de la ville;Raison social;Métier de l’utilisateur;Statut;Nom du responsable;Numéro IBAN;Numéro de SIRET;Site internet;Compte de monnaie locale;Horaires (non obligatoire, html);Description (html);Prénom de l’utilisateur;Nom de l’utilisateur;Courriel / Email;Téléphone fixe;Téléphone mobile;Rubriques (séparés par une virgule);"10:2018,10:2019" Groupe local n°1;2, rue Charles de gaulle;12345;Paris;Nom du prestataire;0;Directeur;SARL;Jean Dupont;FR7630001007941234567890185;732 829 320 00074;www.siteweb.com;Dimanche de 8h à 12h;<b>Description du prestataire</b>;Amap,Fruits,Légumes,Marchés;tag1,tag2;2;10:2017,10:2018,10:2019;john.doe@email.com;Doe;John;0123456789;0623456789;M. Jean Dupont;0123456789;jean.dupont@email.com;Contact comptoir;0198765432;contact.comptoir@email.com
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 Groupe local n°2;;12345;Paris;Nom du prestataire;0;Directeur;SARL;Jean Dupont;FR7630001007941234567890185;732 829 320 00074;www.siteweb.com;Dimanche de 8h à 12h;<b>Description du prestataire</b>;Amap,Fruits,Légumes,Marchés;tag1,tag2;2;10:2017,10:2018,10:2019;john.doe@email.com;Doe;John;0123456789;0623456789;M. Jean Dupont;0123456789;jean.dupont@email.com;Contact comptoir;0198765432;contact.comptoir@email.com
\ No newline at end of file ;a;12345;Paris;Nom du prestataire;0;Directeur;SARL;Jean Dupont;FR7630001007941234567890185;732 829 320 00074;www.siteweb.com;Dimanche de 8h à 12h;<b>Description du prestataire</b>;Amap,Fruits,Légumes,Marchés;tag1,tag2;2;10:2017,10:2018,10:2019;john.doe@email.com;Doe;John;0123456789;0623456789;M. Jean Dupont;0123456789;jean.dupont@email.com;Contact comptoir;0198765432;contact.comptoir@email.com
Groupe local n°3;a;;Paris;Nom du prestataire;0;Directeur;SARL;Jean Dupont;FR7630001007941234567890185;732 829 320 00074;www.siteweb.com;Dimanche de 8h à 12h;<b>Description du prestataire</b>;Amap,Fruits,Légumes,Marchés;tag1,tag2;2;10:2017,10:2018,10:2019;john.doe@email.com;Doe;John;0123456789;0623456789;M. Jean Dupont;0123456789;jean.dupont@email.com;Contact comptoir;0198765432;contact.comptoir@email.com
Groupe local n°4;a;75001;;Nom du prestataire;0;Directeur;SARL;Jean Dupont;FR7630001007941234567890185;732 829 320 00074;www.siteweb.com;Dimanche de 8h à 12h;<b>Description du prestataire</b>;Amap,Fruits,Légumes,Marchés;tag1,tag2;2;10:2017,10:2018,10:2019;john.doe@email.com;Doe;John;0123456789;0623456789;M. Jean Dupont;0123456789;jean.dupont@email.com;Contact comptoir;0198765432;contact.comptoir@email.com
Groupe local n°5;a;75001;Paris;;0;Directeur;SARL;Jean Dupont;FR7630001007941234567890185;732 829 320 00074;www.siteweb.com;Dimanche de 8h à 12h;<b>Description du prestataire</b>;Amap,Fruits,Légumes,Marchés;tag1,tag2;2;10:2017,10:2018,10:2019;john.doe@email.com;Doe;John;0123456789;0623456789;M. Jean Dupont;0123456789;jean.dupont@email.com;Contact comptoir;0198765432;contact.comptoir@email.com
;;;;;;;;Jean Dupont;FR7630001007941234567890185;732 829 320 00074;www.siteweb.com;Dimanche de 8h à 12h;<b>Description du prestataire</b>;Amap,Fruits,Légumes,Marchés;tag1,tag2;2;10:2017,10:2018,10:2019;john.doe@email.com;Doe;John;0123456789;0623456789;M. Jean Dupont;0123456789;jean.dupont@email.com;Contact comptoir;0198765432;contact.comptoir@email.com
...@@ -8,6 +8,7 @@ use Sonata\AdminBundle\Datagrid\ListMapper; ...@@ -8,6 +8,7 @@ use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper; use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Form\Type\Filter\ChoiceType; use Sonata\AdminBundle\Form\Type\Filter\ChoiceType;
use Sonata\AdminBundle\Route\RouteCollection; use Sonata\AdminBundle\Route\RouteCollection;
use Sonata\AdminBundle\Show\ShowMapper;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Translation\TranslatorInterface;
...@@ -21,19 +22,108 @@ class ImportAdmin extends AbstractAdmin ...@@ -21,19 +22,108 @@ class ImportAdmin extends AbstractAdmin
{ {
protected $baseRoutePattern = 'importdata'; protected $baseRoutePattern = 'importdata';
protected $baseRouteName = 'importdata'; protected $baseRouteName = 'importdata';
protected $datagridValues = [
// reverse order (default = 'ASC')
'_sort_order' => 'DESC',
// name of the ordered field (default = the model's id field, if any)
'_sort_by' => 'createdAt',
// '_page' => 1,
// '_per_page' => 32
];
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function configureRoutes(RouteCollection $collection) protected function configureRoutes(RouteCollection $collection)
{ {
$collection->clearExcept('list'); $collection->clearExcept(array('list', 'create', 'show'));
}
/**
* {@inheritdoc}
*/
public function createQuery($context = 'list')
{
$query = parent::createQuery($context);
$query
->innerJoin($query->getRootAliases()[0] .'.user', 'u')
->addSelect('u')
;
return $query;
}
public function configureActionButtons($action, $object = null)
{
$list = parent::configureActionButtons($action, $object);
$list['create']['template'] = '@SonataAdmin/CRUD/import_button.html.twig';
// $list['show']['template'] = '@SonataAdmin/CRUD/import_button.html.twig';
return $list;
} }
protected function configureListFields(ListMapper $listMapper): void protected function configureListFields(ListMapper $listMapper): void
{ {
parent::configureListFields($listMapper); parent::configureListFields($listMapper);
unset($this->listModes['mosaic']); unset($this->listModes['mosaic']);
$listMapper
->addIdentifier('createdAt', 'datetime', ['label' => 'Date'])
->add('user', null, ['label' => 'Utilisateur'])
->addIdentifier('type')
->add('nbentityadded', null, ['label' => 'Lignes correctes'])
->add('nbentityerror', null, ['label' => 'Lignes en erreurs'])
->add('media', null, ['label' => 'Fichier'])
->add('_action', null, [
'actions' => [
'show' => [],
]
])
;
}
protected function configureShowFields(ShowMapper $showMapper): void
{
$object = $showMapper->getAdmin()->getSubject();
$showMapper
->with('Import')
->add('createdAt')
->add('user')
->add('type')
->add('media')
->add('nbentityadded', null, ['label' => 'Lignes correctes'])
->add('nbentityerror', null, ['label' => 'Lignes en erreurs'])
->end();
if (!empty(json_decode($object->getSuccess()))) {
$showMapper
->with('Correct', [
'box_class' => 'box box-solid box-success',
// 'description' => 'Lorem ipsum',
])
->add('success', 'json', ['label' => false])
->end()
;
}
if (!empty(json_decode($object->getWarnings()))) {
$showMapper
->with('Warnings', [
'box_class' => 'box box-solid box-warning',
// 'description' => 'Lorem ipsum',
])
->add('warnings', 'json', ['label' => false])
->end()
;
}
if (!empty(json_decode($object->getErrors()))) {
$showMapper
->with('Erreurs', [
'box_class' => 'box box-solid box-danger',
// 'description' => 'Lorem ipsum',
])
->add('errors', 'json', ['label' => false])
->end()
;
}
;
} }
public function getBatchActions() public function getBatchActions()
......
...@@ -89,7 +89,7 @@ class AdminController extends Controller ...@@ -89,7 +89,7 @@ class AdminController extends Controller
/** /**
* @Route("/admin/getcsv", name="getcsv") * @Route("/admin/getcsv", name="getcsv")
* @IsGranted({"ROLE_ADMIN_IMPORT_EDIT", "ROLE_ADMIN_IMPORT_LIST", "ROLE_ADMIN_IMPORT_CREATE", "ROLE_ADMIN_IMPORT_VIEW", "ROLE_ADMIN_IMPORT_DELETE", "ROLE_ADMIN_IMPORT_EXPORT", "ROLE_ADMIN_IMPORT_ALL"}) * @IsGranted({"ROLE_SUPER_ADMIN", "ROLE_ADMIN_IMPORT_EDIT", "ROLE_ADMIN_IMPORT_LIST", "ROLE_ADMIN_IMPORT_CREATE", "ROLE_ADMIN_IMPORT_VIEW", "ROLE_ADMIN_IMPORT_DELETE", "ROLE_ADMIN_IMPORT_EXPORT", "ROLE_ADMIN_IMPORT_ALL"})
*/ */
public function getCsvAction(Request $request) public function getCsvAction(Request $request)
{ {
......
...@@ -2,9 +2,14 @@ ...@@ -2,9 +2,14 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Adherent; use App\Entity\Adherent;
use App\Entity\ContactComptoir;
use App\Entity\ContactPrestataire;
use App\Entity\Comptoir; use App\Entity\Comptoir;
use App\Entity\Cotisation; use App\Entity\CotisationAdherent;
use App\Entity\CotisationPrestataire;
use App\Entity\EtatPrestataire;
use App\Entity\Geoloc; use App\Entity\Geoloc;
use App\Entity\GeolocPrestataire;
use App\Entity\Groupe; use App\Entity\Groupe;
use App\Entity\Import; use App\Entity\Import;
use App\Entity\Prestataire; use App\Entity\Prestataire;
...@@ -12,11 +17,19 @@ use App\Entity\Rubrique; ...@@ -12,11 +17,19 @@ use App\Entity\Rubrique;
use App\Entity\Siege; use App\Entity\Siege;
use App\Entity\User; use App\Entity\User;
use App\Entity\Usergroup; use App\Entity\Usergroup;
use App\Enum\ImportEnum;
use App\Enum\MoyenEnum; use App\Enum\MoyenEnum;
use App\Events\MLCEvents;
use App\Form\Type\ImportFormType; use App\Form\Type\ImportFormType;
use Gedmo\Sluggable\Util as Sluggable;
use Behat\Transliterator\Transliterator;
use DateTime; use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface; use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use FOS\UserBundle\Util\UserManipulator; use FOS\UserBundle\Util\UserManipulator;
use Sonata\AdminBundle\Controller\CRUDController; use Sonata\AdminBundle\Controller\CRUDController;
use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\Finder;
...@@ -31,6 +44,8 @@ class ImportController extends CRUDController ...@@ -31,6 +44,8 @@ class ImportController extends CRUDController
protected $header; protected $header;
protected $warnings; protected $warnings;
protected $errors; protected $errors;
protected $nberrors;
protected $nbsuccess;
protected $success; protected $success;
protected $lineErrors; protected $lineErrors;
protected $em; protected $em;
...@@ -38,21 +53,26 @@ class ImportController extends CRUDController ...@@ -38,21 +53,26 @@ class ImportController extends CRUDController
protected $security; protected $security;
protected $userManager; protected $userManager;
protected $translator; protected $translator;
protected $tokenGenerator;
public function __construct(EntityManagerInterface $em, Security $security, UserManagerInterface $userManager, TranslatorInterface $translator) public function __construct(EntityManagerInterface $em, Security $security, UserManagerInterface $userManager, TranslatorInterface $translator, TokenGeneratorInterface $tokenGenerator)
{ {
$this->header = null; $this->header = null;
$this->warnings = array(); $this->warnings = array();
$this->errors = array(); $this->errors = array();
$this->nberrors = 0;
$this->nbsuccess = 0;
$this->lineErrors = array(); $this->lineErrors = array();
$this->em = $em; $this->em = $em;
$this->security = $security; $this->security = $security;
$this->userManager = $userManager; $this->userManager = $userManager;
$this->translator = $translator; $this->translator = $translator;
$this->tokenGenerator = $tokenGenerator;
$this->siege = null; $this->siege = null;
$this->sendemail = false;
} }
public function listAction() public function createAction()
{ {
$this->siege = $this->em->getRepository(Siege::class)->findOneById(1); $this->siege = $this->em->getRepository(Siege::class)->findOneById(1);
$import = new Import(); $import = new Import();
...@@ -63,24 +83,39 @@ class ImportController extends CRUDController ...@@ -63,24 +83,39 @@ class ImportController extends CRUDController
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$import = $form->getData(); $import = $form->getData();
$media = $import->getMedia(); $media = $import->getMedia();
$type = $import->getType();
$this->sendemail = (bool)$import->getSendemail();
// Sauvegarder l'import en base de données avant l'essai d'import // Sauvegarder l'import en base de données avant l'essai d'import
$this->em->persist($import); $this->em->persist($import);
$this->em->flush(); $this->em->flush();
$idimport = $import->getId(); $idimport = $import->getId();
$this->importFromCSV($media); $this->importFromCSV($type, $media);
$import = $this->em->getRepository(Import::class)->findOneById($idimport);
$import->setEnabled(true);
$import->setSuccess(json_encode($this->success));
$import->setWarnings(json_encode($this->warnings));
$import->setErrors(json_encode($this->errors));
$import->setNbentityadded($this->nbsuccess);
$import->setNbentityerror($this->nberrors);
$this->em->persist($import);
$this->em->flush();
if (empty($this->errors)) { if (empty($this->errors)) {
$import = $this->em->getRepository(Import::class)->findOneById($idimport);
$import->setEnabled(true);
$this->em->persist($import);
$this->em->flush();
$this->addFlash( $this->addFlash(
'success', 'success',
'Import effectué avec succès !' 'Import effectué avec succès !'
); );
} else {
$this->addFlash(
'error',
"Il y a eu des erreurs lors de l'import !"
);
} }
return $this->redirect($this->admin->generateUrl('show', array('id' => $import->getId())));
} }
return $this->renderWithExtraParams('admin/import.html.twig', array( return $this->renderWithExtraParams('admin/import.html.twig', array(
'action' => 'list', 'action' => 'list',
...@@ -93,7 +128,7 @@ class ImportController extends CRUDController ...@@ -93,7 +128,7 @@ class ImportController extends CRUDController
)); ));
} }
private function importFromCSV($media) private function importFromCSV($type, $media)
{ {
// Turning off doctrine default logs queries for saving memory // Turning off doctrine default logs queries for saving memory
$this->em->getConnection()->getConfiguration()->setSQLLogger(null); $this->em->getConnection()->getConfiguration()->setSQLLogger(null);
...@@ -106,73 +141,84 @@ class ImportController extends CRUDController ...@@ -106,73 +141,84 @@ class ImportController extends CRUDController
$config = $this->getParameter('app.import.header'); $config = $this->getParameter('app.import.header');
if ($this->header == $config['adherent']['header']) { if ($type == ImportEnum::IMPORT_ADHERENT) {
$result = $this->importAdherent($csvRows); $result = $this->importAdherent($csvRows);
} elseif ($this->header == $config['prestataire']['header']) { } elseif ($type == ImportEnum::IMPORT_PRESTATAIRE) {
$result = $this->importPrestataire($csvRows); $result = $this->importPrestataire($csvRows);
} elseif ($this->header == $config['groupe']['header']) { } elseif ($type == ImportEnum::IMPORT_GROUPE) {
$result = $this->importGroupe($csvRows); $result = $this->importGroupe($csvRows);
} elseif ($this->header == $config['comptoir']['header']) { } elseif ($type == ImportEnum::IMPORT_COMPTOIR) {
$result = $this->importComptoir($csvRows); $result = $this->importComptoir($csvRows);
} else { } else {
$this->errors['error'] = $this->translator->trans('CSV invalide'); // Ne devrait jamais arriver, mais sait-on jamais !
$this->errors['error'] = $this->translator->trans('Choisir un type de données à importer !');
} }
return $result; return $result;
} }
private function slugify($string)
{
$string = Transliterator::transliterate($string, '-');
return Transliterator::urlize($string, '-');
}
private function importComptoir($csvRows) private function importComptoir($csvRows)
{ {
// Iterate over the reader and write each row to the database // Iterate over the reader and write each row to the database
// groupe;name;content;phone;mobile;adresse;cpostal;ville;compte //groupe;nom;description;adresse;cpostal;ville;latitude;longitude;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;contact1;phone1;email1;contact2;phone2;email2
$line = 0; $line = 1;
foreach ($csvRows as $row) { foreach ($csvRows as $row) {
if ($line == 0) { if ($line == 1) {
$line++; $line++;
continue; continue;
} }
$groupe = $row['groupe']; if (!(array_key_exists("groupe", $row) && array_key_exists("nom", $row))) {
$name = $row['name']; $this->addError($row, $line, 'nom & groupe', $this->translator->trans("Les colonnes 'nom' et 'groupe' sont obligatoires !"));
$content = $row['content']; $this->nberrors++;
$phone = $row['phone'];
$adresse = $row['adresse'];
$cpostal = $row['cpostal'];
$ville = $row['ville'];
$compte = $row['compte'];
if (empty($groupe) && empty($name)) {
$this->addError($row, $line, 'nom & groupe', $this->translator->trans("Le nom et le groupe sont obligatoires !"));
$line++; $line++;
continue; continue;
} }
$comptoir = $this->em->getRepository(Comptoir::class)->findOneBy(array('name' => $name, 'groupe' => $groupe));
$groupe = array_key_exists("groupe", $row) ? $row['groupe'] : '';
$nom = array_key_exists("nom", $row) ? $row['nom'] : '';
if (empty($groupe)) {
$this->addError($row, $line, 'groupe', $this->translator->trans("Le 'groupe' est obligatoire !"));
$this->nberrors++;
$line++;
continue;
}
if (empty($nom)) {
$this->addError($row, $line, 'nom', $this->translator->trans("Le 'nom' est obligatoire !"));
$this->nberrors++;
$line++;
continue;
}
$description = array_key_exists("description", $row) ? $row['description'] : '';
$adresse = array_key_exists("adresse", $row) ? $row['adresse'] : '';
$cpostal = array_key_exists("cpostal", $row) ? $row['cpostal'] : '';
$ville = array_key_exists("ville", $row) ? $row['ville'] : '';
$latitude = array_key_exists("latitude", $row) ? $row['latitude'] : '';
$longitude = array_key_exists("longitude", $row) ? $row['longitude'] : '';
$compte = array_key_exists("compte", $row) ? $row['compte'] : '';
$groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(array('slug' => $this->slugify($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 = $this->em->getRepository(Comptoir::class)->findOneBy(array('slug' => $this->slugify($nom), 'groupe' => $groupeFound));
if (empty($comptoir)) { if (empty($comptoir)) {
$comptoir = new Comptoir(); $comptoir = new Comptoir();
if (!empty($groupe)) { $comptoir->setGroupe($groupeFound);
$groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(array('name' => $groupe)); $comptoir->setName($nom);
if (empty($groupeFound)) { if (!empty($description)) {
$groupeFound = new Groupe(); $comptoir->setContent($description);
$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 { } else {
$this->addWarning($row, $line, 'content', 'empty'); $this->addWarning($row, $line, 'description', 'empty');
}
if (!empty($phone)) {
$comptoir->setTel($phone);
} else {
$this->addWarning($row, $line, 'phone', 'empty');
} }
if (!empty($compte)) { if (!empty($compte)) {
$comptoir->setCompte($this->tofloat($compte)); $comptoir->setCompte($this->tofloat($compte));
...@@ -184,14 +230,41 @@ class ImportController extends CRUDController ...@@ -184,14 +230,41 @@ class ImportController extends CRUDController
$geolocFound->setAdresse($adresse); $geolocFound->setAdresse($adresse);
$geolocFound->setCpostal(intval($cpostal)); $geolocFound->setCpostal(intval($cpostal));
$geolocFound->setVille($ville); $geolocFound->setVille($ville);
if (!empty($latitude) && !empty($longitude)) {
$geolocFound->setLat((float)$latitude);
$geolocFound->setLon((float)$longitude);
}
$comptoir->setGeoloc($geolocFound); $comptoir->setGeoloc($geolocFound);
} }
$this->addSuccess($row, $line, 'comptoir', $this->translator->trans('Comptoir ajouté : ').$name); // Importer les contacts du comptoir s'ils existent (par défaut en public)
$cptContact = 1;
while (array_key_exists("contact".$cptContact, $row) && $cptContact < 10) {
$contact = array_key_exists('contact'.$cptContact, $row) ? $row['contact'.$cptContact] : '';
$phone = array_key_exists('phone'.$cptContact, $row) ? $row['phone'.$cptContact] : '';
$email = array_key_exists('email'.$cptContact, $row) ? $row['email'.$cptContact] : '';
$contactC = new ContactComptoir();
$contactC->setComptoir($comptoir);
$contactC->setEnabled(true);
$contactC->setName($contact);
$contactC->setTel($phone);
$contactC->setEmail($email);
$this->em->persist($contactC);
++$cptContact;
}
// Importer les gestionnaires de comptoir s'ils existent
$groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Comptoir');
$gestionnaires = $this->importGestionnaires($row, $groupeGestionnaire);
$comptoir->setGestionnaires($gestionnaires);
$this->addSuccess($row, $line, 'comptoir', $this->translator->trans('Comptoir ajouté : ').$nom);
$this->nbsuccess++;
$this->em->persist($comptoir); $this->em->persist($comptoir);
$this->em->flush(); $this->em->flush();
$this->em->clear(); $this->em->clear();
} else { } else {
$this->addError($row, $line, 'name', $this->translator->trans("Le comptoir avec ce nom '".$name."' existe déjà !")); $this->addError($row, $line, 'nom', $this->translator->trans("Le comptoir avec ce nom {name} existe déjà !", ['name' => $nom]));
$this->nberrors++;
} }
$line++; $line++;
...@@ -203,17 +276,23 @@ class ImportController extends CRUDController ...@@ -203,17 +276,23 @@ class ImportController extends CRUDController
private function importGroupe($csvRows) private function importGroupe($csvRows)
{ {
// Iterate over the reader and write each row to the database // Iterate over the reader and write each row to the database
// name;content;compte // nom;description;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1
$line = 0; $line = 1;
foreach ($csvRows as $row) { foreach ($csvRows as $row) {
if ($line == 0) { if ($line == 1) {
$line++; $line++;
continue; continue;
} }
$name = $row['name']; $name = array_key_exists("nom", $row) ? $row['nom'] : '';
$content = $row['content']; if (empty($name)) {
$compte = $row['compte']; $this->addError($row, $line, 'nom', $this->translator->trans("Le 'nom' est obligatoire !"));
$groupe = $this->em->getRepository(Groupe::class)->findOneBy(array('name' => $name)); $this->nberrors++;
$line++;
continue;
}
$description = array_key_exists("description", $row) ? $row['description'] : '';
$compte = array_key_exists("compte", $row) ? $row['compte'] : '';
$groupe = $this->em->getRepository(Groupe::class)->findOneBy(array('slug' => $this->slugify($name)));
if (empty($groupe)) { if (empty($groupe)) {
$groupe = new Groupe(); $groupe = new Groupe();
$groupe->setSiege($this->em->getRepository(Siege::class)->findOneById(1)); $groupe->setSiege($this->em->getRepository(Siege::class)->findOneById(1));
...@@ -232,12 +311,19 @@ class ImportController extends CRUDController ...@@ -232,12 +311,19 @@ class ImportController extends CRUDController
} else { } else {
$this->addWarning($row, $line, 'compte', 'empty'); $this->addWarning($row, $line, 'compte', 'empty');
} }
// Importer les gestionnaires du groupe s'ils existent
$groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Gestionnaire de Groupe');
$gestionnaires = $this->importGestionnaires($row, $groupeGestionnaire);
$groupe->setGestionnaires($gestionnaires);
$this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ').$name); $this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ').$name);
$this->em->persist($groupe); $this->em->persist($groupe);
$this->nbsuccess++;
$this->em->flush(); $this->em->flush();
$this->em->clear(); $this->em->clear();
} else { } else {
$this->addError($row, $line, 'name', $this->translator->trans("Le groupe avec ce nom '".$name."' existe déjà !")); $this->addError($row, $line, 'name', $this->translator->trans("Le groupe avec ce nom '".$name."' existe déjà !"));
$this->nberrors++;
} }
$line++; $line++;
} }
...@@ -248,166 +334,239 @@ class ImportController extends CRUDController ...@@ -248,166 +334,239 @@ class ImportController extends CRUDController
private function importPrestataire($csvRows) private function importPrestataire($csvRows)
{ {
// Iterate over the reader and write each row to the database // 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 // groupe;adresse;cpostal;ville;raison;ecompte;metier;statut;responsable;iban;siret;web;horaires;description;rubriques;tags;tauxreconversion;cotisations;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;contact1;phone1;email1;contact2;phone2;email2
$line = 0; $line = 1;
foreach ($csvRows as $row) { foreach ($csvRows as $row) {
$hasError = false; $hasError = false;
if ($line == 0) { if ($line == 1) {
$line++; $line++;
continue; continue;
} }
$groupe = $row['groupe']; if (!array_key_exists("groupe", $row)) {
$adresse = $row['adresse']; $this->addError($row, $line, 'groupe', $this->translator->trans("La colonne 'groupe' est obligatoire !"));
$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);
$prestataire->addUser($user);
if (!empty($raison)) {
$prestataire->setRaison($raison);
} else {
$this->addWarning($row, $line, 'raison', 'empty');
} }
if (!empty($metier)) { if (!array_key_exists("adresse", $row)) {
$prestataire->setMetier($metier); $this->addError($row, $line, 'adresse', $this->translator->trans("La colonne 'adresse' est obligatoire !"));
} else {
$this->addWarning($row, $line, 'metier', 'empty');
} }
if (!empty($statut)) { if (!array_key_exists("cpostal", $row)) {
$prestataire->setStatut($statut); $this->addError($row, $line, 'cpostal', $this->translator->trans("La colonne 'cpostal' est obligatoire !"));
} else {
$this->addWarning($row, $line, 'statut', 'empty');
} }
if (!empty($responsable)) { if (!array_key_exists("ville", $row)) {
$prestataire->setResponsable($responsable); $this->addError($row, $line, 'ville', $this->translator->trans("La colonne 'ville' est obligatoire !"));
} else {
$this->addWarning($row, $line, 'responsable', 'empty');
} }
if (!empty($iban)) { if (!array_key_exists("raison", $row)) {
$prestataire->setIban($iban); $this->addError($row, $line, 'raison', $this->translator->trans("La colonne 'raison' est obligatoire !"));
} else {
$this->addWarning($row, $line, 'iban', 'empty');
} }
if (!empty($siret)) { if (!(array_key_exists("groupe", $row) && array_key_exists("adresse", $row) && array_key_exists("cpostal", $row) && array_key_exists("ville", $row) && array_key_exists("raison", $row))) {
$prestataire->setSiret($siret); $line++;
} else { $this->nberrors++;
$this->addWarning($row, $line, 'siret', 'empty'); continue;
} }
if (!empty($web)) { $groupe = array_key_exists("groupe", $row) ? $row['groupe'] : '';
$prestataire->setWeb($web); $adresse = array_key_exists("adresse", $row) ? $row['adresse'] : '';
} else { $cpostal = array_key_exists("cpostal", $row) ? $row['cpostal'] : '';
$this->addWarning($row, $line, 'web', 'empty'); $ville = array_key_exists("ville", $row) ? $row['ville'] : '';
$raison = array_key_exists("raison", $row) ? $row['raison'] : '';
if (empty($groupe)) {
$this->addError($row, $line, 'groupe', $this->translator->trans("Le 'groupe' est obligatoire !"));
} }
if (!empty($horaires)) { if (empty($adresse)) {
$prestataire->setHoraires($horaires); $this->addError($row, $line, 'adresse', $this->translator->trans("Le 'adresse' est obligatoire !"));
} else {
$this->addWarning($row, $line, 'horaires', 'empty');
} }
if (!empty($description)) { if (empty($cpostal)) {
$prestataire->setDescription($description); $this->addError($row, $line, 'cpostal', $this->translator->trans("Le 'cpostal' est obligatoire !"));
} else {
$this->addWarning($row, $line, 'description', 'empty');
} }
if (!empty($firstname)) { if (empty($ville)) {
$user->setFirstname($firstname); $this->addError($row, $line, 'ville', $this->translator->trans("Le 'ville' est obligatoire !"));
} else {
$this->addWarning($row, $line, 'firstname', 'empty');
} }
if (!empty($lastname)) { if (empty($raison)) {
$user->setLastname($lastname); $this->addError($row, $line, 'raison', $this->translator->trans("Le 'raison' est obligatoire !"));
} else {
$this->addWarning($row, $line, 'lastname', 'empty');
} }
if (!empty($email)) { if (empty($groupe) || empty($adresse) || empty($cpostal) || empty($ville) || empty($raison)) {
$userFound = $this->em->getRepository(User::class)->findOneBy(array('email' => $email)); $this->nberrors++;
if (!empty($userFound)) { $line++;
$hasError = true; continue;
$this->addError($row, $line, 'email', $this->translator->trans("L'email est déjà utilisé !")); }
$line++; $ecompte = array_key_exists("ecompte", $row) ? $row['ecompte'] : '';
continue; $metier = array_key_exists("metier", $row) ? $row['metier'] : '';
$statut = array_key_exists("statut", $row) ? $row['statut'] : '';
$responsable = array_key_exists("responsable", $row) ? $row['responsable'] : '';
$iban = array_key_exists("iban", $row) ? $row['iban'] : '';
$siret = array_key_exists("siret", $row) ? $row['siret'] : '';
$web = array_key_exists("web", $row) ? $row['web'] : '';
$horaires = array_key_exists("horaires", $row) ? $row['horaires'] : '';
$description = array_key_exists("description", $row) ? $row['description'] : '';
$rubriques = array_key_exists("rubriques", $row) ? $row['rubriques'] : '';
$tags = array_key_exists("tags", $row) ? $row['tags'] : '';
$tauxreconversion = array_key_exists("tauxreconversion", $row) ? $row['tauxreconversion'] : '';
$cotisations = array_key_exists("cotisations", $row) ? $row['cotisations'] : '';
$prestataire = $this->em->getRepository(Prestataire::class)->findOneBy(array('slug' => $this->slugify($raison)));
if (empty($prestataire)) {
$prestataire = new Prestataire();
if (!empty($raison)) {
$prestataire->setRaison($raison);
} else { } else {
$user->setEmail($email); $this->addWarning($row, $line, 'raison', 'empty');
$user->setUsername($email);
} }
} else { if (!empty($metier)) {
$this->addWarning($row, $line, 'email', 'empty'); $prestataire->setMetier($metier);
} } else {
if (!empty($phone)) { $this->addWarning($row, $line, 'metier', 'empty');
$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); if (!empty($statut)) {
} else { $prestataire->setStatut($statut);
$this->addWarning($row, $line, 'groupe', 'empty'); } else {
} $this->addWarning($row, $line, 'statut', 'empty');
if (!empty($rubriques)) { }
$rubriquesArray = explode(',', $rubriques); if (!empty($responsable)) {
foreach ($rubriquesArray as $rubrique) { $prestataire->setResponsable($responsable);
$rubriquesFound = $this->em->getRepository(Rubrique::class)->findOneBy(array('name' => $rubrique)); } else {
if (empty($rubriquesFound)) { $this->addWarning($row, $line, 'responsable', 'empty');
$rubriquesFound = new Rubrique(); }
$rubriquesFound->setName($rubrique); if (!empty($iban)) {
$this->em->persist($rubriquesFound); $prestataire->setIban($iban);
$this->addSuccess($row, $line, 'rubrique', $this->translator->trans('Rubrique ajoutée : ').$rubrique); } 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');
}
$cptContact = 1;
while (array_key_exists("contact".$cptContact, $row) && $cptContact < 10) {
$contact = array_key_exists('contact'.$cptContact, $row) ? $row['contact'.$cptContact] : '';
$phone = array_key_exists('phone'.$cptContact, $row) ? $row['phone'.$cptContact] : '';
$email = array_key_exists('email'.$cptContact, $row) ? $row['email'.$cptContact] : '';
$contactC = new ContactPrestataire();
$contactC->setPrestataire($prestataire);
$contactC->setEnabled(true);
$contactC->setName($contact);
$contactC->setTel($phone);
$contactC->setEmail($email);
$this->em->persist($contactC);
++$cptContact;
}
// Importer les gestionnaires du prestataire s'ils existent
$groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Prestataire');
$gestionnaires = $this->importGestionnaires($row, $groupeGestionnaire);
$prestataire->setUsers($gestionnaires);
if (!empty($ecompte)) {
$prestataire->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->addWarning($row, $line, 'groupe', $this->translator->trans('Groupe introuvable, création du groupe : ').$groupe);
}
$prestataire->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 CotisationPrestataire();
$now = new DateTime();
$cotisation->setReference('Import du '.$now->format('d/m/Y H:i'));
$cotisation->setOperateur($this->getUser());
$cotisation->setRole('ROLE_SUPER_ADMIN');
$cotisation->setExpediteur($prestataire);
$cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE);
$cotisationDetailsArray = explode(':', $cotisationDetails);
if (count($cotisationDetailsArray) == 1) {
$cotisation->setMontant(intval($cotisationDetails));
$cotisation->getCotisationInfos()->setDebut($now);
$cotisation->getCotisationInfos()->setFin(new DateTime('+ 1 year'));
} else {
$cotisation->setMontant(intval($cotisationDetailsArray[0]));
$cotisation->getCotisationInfos()->setAnnee(intval($cotisationDetailsArray[1]));
$cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101'));
$cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231'));
}
$this->em->persist($cotisation);
$this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation ajouté : ').$groupe);
}
}
} else {
$this->addWarning($row, $line, 'cotisations', 'empty');
}
if (!empty($rubriques)) {
$rubriquesArray = explode(',', $rubriques);
foreach ($rubriquesArray as $rubrique) {
$rubriquesFound = $this->em->getRepository(Rubrique::class)->findOneBy(array('slug' => $this->slugify($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($tags)) {
$tagsArray = explode(',', $tags);
foreach ($tagsArray as $tag) {
$tagsFound = $this->em->getRepository(EtatPrestataire::class)->findOneBy(array('slug' => $this->slugify($tag)));
if (empty($tagsFound)) {
$tagNew = new EtatPrestataire();
$tagNew->setName($tag);
$this->em->persist($tagNew);
$this->addSuccess($row, $line, 'tag', $this->translator->trans('Tag ajouté : ').$tag);
}
} }
} else {
$this->addWarning($row, $line, 'tags', 'empty');
}
if (!empty($adresse) || !empty($cpostal) || !empty($ville)) {
$geolocP = new GeolocPrestataire();
$geolocP->setName('Adresse');
$geolocP->setPrestataire($prestataire);
$geolocFound = new Geoloc();
$geolocFound->setEnabled(true);
$geolocFound->setAdresse($adresse);
$geolocFound->setCpostal(intval($cpostal));
$geolocFound->setVille($ville);
$geolocP->setGeoloc($geolocFound);
$prestataire->setGeolocs([$geolocP]);
$this->em->persist($geolocP);
} }
} else { } else {
$this->addWarning($row, $line, 'rubriques', 'empty'); $this->addError($row, $line, 'name', $this->translator->trans("Le prestataire avec cette raison '".$raison."' existe déjà !"));
} $this->nberrors++;
if (!empty($adresse) || !empty($cpostal) || !empty($ville)) { $hasError = true;
$geolocFound = new Geoloc();
$geolocFound->setAdresse($adresse);
$geolocFound->setCpostal(intval($cpostal));
$geolocFound->setVille($ville);
$prestataire->setGeoloc($geolocFound);
} }
if (!$hasError) { if (!$hasError) {
$this->addSuccess($row, $line, 'user', $this->translator->trans('Prestataire bien ajouté : ').$user->__toString()); $this->addSuccess($row, $line, 'user', $this->translator->trans('Prestataire bien ajouté : ').$prestataire->__toString());
$this->userManager->updateUser($user); $this->nbsuccess++;
$this->em->persist($user); $this->em->persist($prestataire);
$this->em->flush(); $this->em->flush();
$this->em->clear(); $this->em->clear();
} }
...@@ -422,32 +581,40 @@ class ImportController extends CRUDController ...@@ -422,32 +581,40 @@ class ImportController extends CRUDController
{ {
// Iterate over the reader and write each row to the database // Iterate over the reader and write each row to the database
// groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte // groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte
$line = 0; $line = 1;
foreach ($csvRows as $row) { foreach ($csvRows as $row) {
$hasError = false; $hasError = false;
if ($line == 0) { if ($line == 1) {
$line++; $line++;
continue; continue;
} }
$groupe = $row['groupe']; $groupe = array_key_exists("groupe", $row) ? $row['groupe'] : '';
$firstname = $row['firstname']; $firstname = array_key_exists("firstname", $row) ? $row['firstname'] : '';
$lastname = $row['lastname']; $lastname = array_key_exists("lastname", $row) ? $row['lastname'] : '';
$email = $row['email']; $email = array_key_exists("email", $row) ? $row['email'] : '';
$phone = $row['phone']; $phone = array_key_exists("phone", $row) ? $row['phone'] : '';
$mobile = $row['mobile']; $mobile = array_key_exists("mobile", $row) ? $row['mobile'] : '';
$adresse = $row['adresse']; $adresse = array_key_exists("adresse", $row) ? $row['adresse'] : '';
$cpostal = $row['cpostal']; $cpostal = array_key_exists("cpostal", $row) ? $row['cpostal'] : '';
$ville = $row['ville']; $ville = array_key_exists("ville", $row) ? $row['ville'] : '';
$ecompte = $row['ecompte']; $ecompte = array_key_exists("ecompte", $row) ? $row['ecompte'] : '';
$cotisations = $row['cotisations']; $cotisations = array_key_exists("cotisations", $row) ? $row['cotisations'] : '';
if (!(array_key_exists("email", $row))) {
$this->addError($row, $line, 'email', $this->translator->trans("La colonne 'email' est obligatoire !"));
$line++;
$this->nberrors++;
continue;
}
$adherent = new Adherent(); $adherent = new Adherent();
$user = $this->userManager->createUser(); $user = $this->userManager->createUser();
$user->setConfirmationToken($this->tokenGenerator->generateToken());
$user->setEnabled(true); $user->setEnabled(true);
$user->setPassword(md5(random_bytes(10))); $user->setPassword(md5(random_bytes(10)));
$user->addRole('ROLE_ADHERENT');
$usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent'); $usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent');
$user->addGroup($usergroupe); $user->addPossiblegroup($usergroupe);
$user->setGroups([$usergroupe]);
$user->setAdherent($adherent); $user->setAdherent($adherent);
$adherent->setUser($user); $adherent->setUser($user);
...@@ -467,6 +634,7 @@ class ImportController extends CRUDController ...@@ -467,6 +634,7 @@ class ImportController extends CRUDController
$hasError = true; $hasError = true;
$this->addError($row, $line, 'email', $this->translator->trans("L'email est déjà utilisé !")); $this->addError($row, $line, 'email', $this->translator->trans("L'email est déjà utilisé !"));
$line++; $line++;
$this->nberrors++;
continue; continue;
} else { } else {
$user->setEmail($email); $user->setEmail($email);
...@@ -507,25 +675,26 @@ class ImportController extends CRUDController ...@@ -507,25 +675,26 @@ class ImportController extends CRUDController
$cotisationArray = explode(',', $cotisations); $cotisationArray = explode(',', $cotisations);
if (count($cotisationArray) > 0) { if (count($cotisationArray) > 0) {
foreach ($cotisationArray as $cotisationDetails) { foreach ($cotisationArray as $cotisationDetails) {
$cotisation = new Cotisation(); $cotisation = new CotisationAdherent();
$now = new DateTime(); $now = new DateTime();
$cotisation->setReference('Import du '.$now->format('d/m/Y H:i')); $cotisation->setReference('Import du '.$now->format('d/m/Y H:i'));
$cotisation->setOperateur($user); $cotisation->setOperateur($this->getUser());
$cotisation->setRole('ROLE_ADHERENT');
$cotisation->setExpediteur($adherent); $cotisation->setExpediteur($adherent);
$cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE); $cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE);
$cotisationDetailsArray = explode(':', $cotisationDetails); $cotisationDetailsArray = explode(':', $cotisationDetails);
if (count($cotisationDetailsArray) == 1) { if (count($cotisationDetailsArray) == 1) {
$cotisation->setMontant(intval($cotisationDetails)); $cotisation->setMontant(intval($cotisationDetails));
$cotisation->setDebut($now); $cotisation->getCotisationInfos()->setDebut($now);
$cotisation->setFin(new DateTime('+ 1 year')); $cotisation->getCotisationInfos()->setFin(new DateTime('+ 1 year'));
} else { } else {
$cotisation->setMontant(intval($cotisationDetailsArray[0])); $cotisation->setMontant(intval($cotisationDetailsArray[0]));
$cotisation->setAnnee(intval($cotisationDetailsArray[1])); $cotisation->getCotisationInfos()->setAnnee(intval($cotisationDetailsArray[1]));
$cotisation->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101')); $cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101'));
$cotisation->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231')); $cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231'));
} }
$user->addCotisation($cotisation); $this->em->persist($cotisation);
// $this->em->persist($cotisation); $this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation ajouté : ').$groupe);
} }
} }
} else { } else {
...@@ -540,8 +709,12 @@ class ImportController extends CRUDController ...@@ -540,8 +709,12 @@ class ImportController extends CRUDController
} }
if (!$hasError) { if (!$hasError) {
$this->addSuccess($row, $line, 'user', $this->translator->trans('Utilisateur bien ajouté : ').$user->__toString()); $this->addSuccess($row, $line, 'user', $this->translator->trans('Utilisateur bien ajouté : ').$user->__toString());
$this->nbsuccess++;
$user->setPasswordRequestedAt(new \DateTime());
$this->userManager->updateUser($user); $this->userManager->updateUser($user);
$this->em->persist($user); if ($this->sendemail) {
$this->eventDispatcher->dispatch(MLCEvents::REGISTRATION_ADHERENT, new UserEvent($user, $this->getRequest()));
}
$this->em->flush(); $this->em->flush();
$this->em->clear(); $this->em->clear();
} }
...@@ -552,16 +725,15 @@ class ImportController extends CRUDController ...@@ -552,16 +725,15 @@ class ImportController extends CRUDController
ksort($this->warnings); ksort($this->warnings);
} }
/**
* Open and parse .CSV file
* @param string $filePath Path of the file
* @param string $fileName Name of the file
* @param boolean $ignoreFirstLine If true, ignore first line
* @return array Array of parsed values with array's key = firstline
*/
private function parseCSV($filePath, $fileName, $ignoreFirstLine = false) private function parseCSV($filePath, $fileName, $ignoreFirstLine = false)
{ {
// $finder = new Finder();
// $finder->files()
// ->in($filePath)
// ->name($fileName)
// ;
// foreach ($finder as $file) {
// $csv = $file;
// }
$csv = new \SplFileObject($filePath.'/'.$fileName); $csv = new \SplFileObject($filePath.'/'.$fileName);
$rows = array(); $rows = array();
...@@ -579,6 +751,7 @@ class ImportController extends CRUDController ...@@ -579,6 +751,7 @@ class ImportController extends CRUDController
} else { } else {
if (count($firstline) != count($data)) { 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 !")); $this->addError($data, $i, 'Ligne entière', $this->translator->trans("La ligne ne contient pas le bon nombre d'éléments requis !"));
$this->nberrors++;
continue; continue;
} }
$rows[] = array_combine(array_values($firstline), array_values($data)); $rows[] = array_combine(array_values($firstline), array_values($data));
...@@ -589,16 +762,64 @@ class ImportController extends CRUDController ...@@ -589,16 +762,64 @@ class ImportController extends CRUDController
return $rows; return $rows;
} }
/**
* Import manager of comptoir / groupe / presta
* @param array $row Value of line imported
* @param Usergroup $groupe Groupe add to manager imported
* @return User Manager created
*/
private function importGestionnaires($row, Usergroup $groupe)
{
$cptGestionnaire = 1;
$users = new ArrayCollection();
while (array_key_exists("gestionnaire_email".$cptGestionnaire, $row) && !empty($row['gestionnaire_email'.$cptGestionnaire]) && $cptGestionnaire < 10) {
$email = array_key_exists('gestionnaire_email'.$cptGestionnaire, $row) ? $row['gestionnaire_email'.$cptGestionnaire] : '';
$userFound = $this->em->getRepository(User::class)->findOneBy(array('email' => $email));
if (!empty($userFound)) {
$userFound->addPossiblegroup($groupe);
$users[] = $userFound;
$this->em->persist($userFound);
} else {
$nom = array_key_exists('gestionnaire_nom'.$cptGestionnaire, $row) ? $row['gestionnaire_nom'.$cptGestionnaire] : '';
$prenom = array_key_exists('gestionnaire_prenom'.$cptGestionnaire, $row) ? $row['gestionnaire_prenom'.$cptGestionnaire] : '';
$phone = array_key_exists('gestionnaire_phone'.$cptGestionnaire, $row) ? $row['gestionnaire_phone'.$cptGestionnaire] : '';
$mobile = array_key_exists('gestionnaire_mobile'.$cptGestionnaire, $row) ? $row['gestionnaire_mobile'.$cptGestionnaire] : '';
$user = $this->userManager->createUser();
$user->setConfirmationToken($this->tokenGenerator->generateToken());
$user->setEnabled(true);
$user->setPassword(md5(random_bytes(10)));
$usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adhérent');
$user->addPossiblegroup($usergroupe);
$user->addPossiblegroup($groupe);
$user->setGroups([$groupe]);
$user->setFirstname($prenom);
$user->setLastname($nom);
$user->setPhone($phone);
$user->setMobile($mobile);
$user->setEmail($email);
$user->setUsername($user->getName());
$users[] = $user;
$this->em->persist($user);
}
if ($this->sendemail) {
$this->eventDispatcher->dispatch(MLCEvents::REGISTRATION_ADHERENT, new UserEvent($user, $this->getRequest()));
}
++$cptGestionnaire;
}
return $users;
}
private function addSuccess($row, $line, $key, $message = '') private function addSuccess($row, $line, $key, $message = '')
{ {
$csvline = implode(';', array_values($row)); $csvline = implode(';', array_values($row));
$this->success[$line][$key][$csvline] = $message; $this->success[$line][$key] = $message;
} }
private function addError($row, $line, $key, $err = '') private function addError($row, $line, $key, $err = '')
{ {
$this->lineErrors[$line] = implode(';', array_values($row)); $this->lineErrors[$line] = implode(';', array_values($row));
$this->errors[$line][$key][$this->lineErrors[$line]] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$err.']'; $this->errors[$line][$key] = (array_key_exists($key, $row)?(!empty($row[$key])?'"'.$row[$key].'"':''):'').' ['.$err.']';
} }
private function addWarning($row, $line, $key, $err = '') private function addWarning($row, $line, $key, $err = '')
...@@ -606,12 +827,12 @@ class ImportController extends CRUDController ...@@ -606,12 +827,12 @@ class ImportController extends CRUDController
$csvline = implode(';', array_values($row)); $csvline = implode(';', array_values($row));
if ($err == 'empty') { if ($err == 'empty') {
$errString = $this->translator->trans('Valeur vide !'); $errString = $this->translator->trans('Valeur vide !');
$this->warnings[$line][$key][$csvline] ='['.$errString.' ]'; $this->warnings[$line][$key] ='['.$errString.' ]';
} elseif ($err == 'invalid') { } elseif ($err == 'invalid') {
$errString = $this->translator->trans('Valeur invalide !'); $errString = $this->translator->trans('Valeur invalide !');
$this->warnings[$line][$key][$csvline] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$errString.']'; $this->warnings[$line][$key] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$errString.']';
} elseif ($err != '') { } elseif ($err != '') {
$this->warnings[$line][$key][$csvline] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$err.']'; $this->warnings[$line][$key] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$err.']';
} }
} }
......
...@@ -42,6 +42,55 @@ class Import ...@@ -42,6 +42,55 @@ class Import
*/ */
private $user; private $user;
/**
* @var string|null
*
* @ORM\Column(type="json", nullable=true)
*/
private $errors;
/**
* @var string|null
*
* @ORM\Column(type="json", nullable=true)
*/
private $success;
/**
* @var string|null
*
* @ORM\Column(type="json", nullable=true)
*/
private $warnings;
/**
* @var string
*
* @ORM\Column(name="type", type="string", length=100)
*/
private $type;
/**
* @var string
*
* @ORM\Column(name="nbentityadded", type="integer", nullable=true)
*/
private $nbentityadded;
/**
* @var string
*
* @ORM\Column(name="nbentityerror", type="integer", nullable=true)
*/
private $nbentityerror;
/**
* @var string
*
* @ORM\Column(name="sendemail", type="string", length=100)
*/
private $sendemail;
public function __construct() public function __construct()
{ {
$this->setEnabled(false); $this->setEnabled(false);
...@@ -92,8 +141,141 @@ class Import ...@@ -92,8 +141,141 @@ class Import
return $this; return $this;
} }
/**
* Get errors
* @return
*/
public function getErrors()
{
return $this->errors;
}
/**
* Set errors
* @return $this
*/
public function setErrors($errors)
{
$this->errors = $errors;
return $this;
}
/**
* Get success
* @return
*/
public function getSuccess()
{
return $this->success;
}
/**
* Set success
* @return $this
*/
public function setSuccess($success)
{
$this->success = $success;
return $this;
}
/**
* Get warnings
* @return
*/
public function getWarnings()
{
return $this->warnings;
}
/**
* Set warnings
* @return $this
*/
public function setWarnings($warnings)
{
$this->warnings = $warnings;
return $this;
}
/**
* Get type
* @return
*/
public function getType(): ?string
{
return $this->type;
}
/**
* Get sendemail
* @return
*/
public function getSendemail()
{
return $this->sendemail;
}
/**
* Set sendemail
* @return $this
*/
public function setSendemail($sendemail)
{
$this->sendemail = $sendemail;
return $this;
}
/**
* Get nbentityadded
* @return
*/
public function getNbentityadded()
{
return $this->nbentityadded;
}
/**
* Set nbentityadded
* @return $this
*/
public function setNbentityadded($nbentityadded)
{
$this->nbentityadded = $nbentityadded;
return $this;
}
/**
* Get nbentityerror
* @return
*/
public function getNbentityerror()
{
return $this->nbentityerror;
}
/**
* Set nbentityerror
* @return $this
*/
public function setNbentityerror($nbentityerror)
{
$this->nbentityerror = $nbentityerror;
return $this;
}
/**
* Set type
* @return $this
*/
public function setType(?string $type): self
{
$this->type = $type;
return $this;
}
public function __toString(): string public function __toString(): string
{ {
return 'Import du '.$this->getCreatedAt()?$this->getCreatedAt()->format('d/m/Y H:i'):'?'; return 'Import de '.$this->getType().' du '.($this->getCreatedAt()?$this->getCreatedAt()->format('d/m/Y H:i'):'?');
} }
} }
...@@ -37,7 +37,6 @@ class Prestataire ...@@ -37,7 +37,6 @@ class Prestataire
{ {
use EnablableEntityTrait, use EnablableEntityTrait,
TimestampableEntity, TimestampableEntity,
HasCompteEntity,
HasEcompteEntity; HasEcompteEntity;
/** /**
...@@ -101,6 +100,7 @@ class Prestataire ...@@ -101,6 +100,7 @@ class Prestataire
/** /**
* @ORM\Column(name="iban", type="string", length=100, nullable=true) * @ORM\Column(name="iban", type="string", length=100, nullable=true)
* @todo : vérification de l'IBAN via assert/iban
* Assert\Iban(message="L'IBAN(International Bank Account Number) est invalide.") * Assert\Iban(message="L'IBAN(International Bank Account Number) est invalide.")
* @Groups({"read", "write"}) * @Groups({"read", "write"})
*/ */
...@@ -109,7 +109,7 @@ class Prestataire ...@@ -109,7 +109,7 @@ class Prestataire
/** /**
* @var string * @var string
* *
* @ORM\Column(name="siret", type="string", length=50) * @ORM\Column(name="siret", type="string", length=50, nullable=true)
* @Groups({"read", "write"}) * @Groups({"read", "write"})
*/ */
private $siret; private $siret;
......
...@@ -531,7 +531,7 @@ class User extends BaseUser ...@@ -531,7 +531,7 @@ class User extends BaseUser
public function __toString() public function __toString()
{ {
if (empty($this->getFullname())) { if (empty(trim($this->getFullname()))) {
return $this->getEmail(); return $this->getEmail();
} }
return $this->getFullname(); return $this->getFullname();
...@@ -539,7 +539,7 @@ class User extends BaseUser ...@@ -539,7 +539,7 @@ class User extends BaseUser
public function getName() public function getName()
{ {
if (empty($this->getFullname())) { if (empty(trim($this->getFullname()))) {
return $this->__toString(); return $this->__toString();
} }
return $this->getFullname(); return $this->getFullname();
......
<?php
namespace App\Enum;
abstract class ImportEnum
{
const IMPORT_GROUPE = "groupe";
const IMPORT_COMPTOIR = "comptoir";
const IMPORT_PRESTATAIRE = "prestataire";
const IMPORT_ADHERENT = "adherent";
/** @var array user friendly named type */
protected static $typeName = [
self::IMPORT_GROUPE => 'Groupe(s)',
self::IMPORT_COMPTOIR => 'Comptoir(s)',
self::IMPORT_PRESTATAIRE => 'Prestataire(s)',
self::IMPORT_ADHERENT => 'Adherent(s)',
];
/**
* @param string $typeShortName
* @return string
*/
public static function getTypeName($typeShortName)
{
if (!isset(static::$typeName[$typeShortName])) {
return "Unknown type ($typeShortName)";
}
return static::$typeName[$typeShortName];
}
/**
* @return array<string>
*/
public static function getAvailableTypes()
{
return [
self::IMPORT_GROUPE,
self::IMPORT_COMPTOIR,
self::IMPORT_PRESTATAIRE,
self::IMPORT_ADHERENT
];
}
}
...@@ -107,14 +107,11 @@ class MLCEventListener implements EventSubscriberInterface ...@@ -107,14 +107,11 @@ class MLCEventListener implements EventSubscriberInterface
public function onFlux(FluxEvent $event) public function onFlux(FluxEvent $event)
{ {
dump("onflux");
foreach ($event->getFlux()->getUsersToNotify() as $user) { foreach ($event->getFlux()->getUsersToNotify() as $user) {
dump($user);
if ($user instanceof User && $user->getAlertemailflux()) { if ($user instanceof User && $user->getAlertemailflux()) {
$this->sendMail($user, $event->getFlux()); $this->sendMail($user, $event->getFlux());
} elseif ($user == 'siege') { } elseif ($user == 'siege') {
$users = $this->em->getRepository(User::class)->findByRole('ROLE_ADMIN_SIEGE'); $users = $this->em->getRepository(User::class)->findByRole('ROLE_ADMIN_SIEGE');
dump($users);
foreach ($users as $userAdminSiege) { foreach ($users as $userAdminSiege) {
if ($userAdminSiege->getAlertemailflux()) { if ($userAdminSiege->getAlertemailflux()) {
$this->sendMail($userAdminSiege, $event->getFlux()); $this->sendMail($userAdminSiege, $event->getFlux());
......
...@@ -4,11 +4,14 @@ namespace App\Form\Type; ...@@ -4,11 +4,14 @@ namespace App\Form\Type;
use App\Entity\Import; use App\Entity\Import;
use App\Entity\User; use App\Entity\User;
use App\Enum\ImportEnum;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Sonata\MediaBundle\Form\Type\MediaType; use Sonata\MediaBundle\Form\Type\MediaType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
...@@ -26,7 +29,7 @@ class ImportFormType extends AbstractType ...@@ -26,7 +29,7 @@ class ImportFormType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
if (empty($this->security) && !empty($this->security->getUser())) { if (empty($this->security) || empty($this->security->getUser())) {
throw new \Exception("Opération impossible ! Utilisateur non connecté !"); throw new \Exception("Opération impossible ! Utilisateur non connecté !");
} }
$builder $builder
...@@ -34,15 +37,29 @@ class ImportFormType extends AbstractType ...@@ -34,15 +37,29 @@ class ImportFormType extends AbstractType
'provider' => 'sonata.media.provider.file', 'provider' => 'sonata.media.provider.file',
'context' => 'import', 'context' => 'import',
'label' => 'Fichier .csv', 'label' => 'Fichier .csv',
'show_unlink' => false 'show_unlink' => false,
'required' => true,
)) ))
->add('user', HiddenType::class, array( ->add('user', HiddenType::class, array(
'data_class' => null, 'data_class' => null,
'data' => $this->security->getUser()->getId(), 'data' => $this->security->getUser()->getId(),
'entity_class' => User::class, 'entity_class' => User::class,
'em' => $this->em 'em' => $this->em
)) ))
->add('type', ChoiceType::class, array(
'label' => 'Choisir le type de données à importer : ',
'placeholder' => '',
'required' => true,
'choices' => ImportEnum::getAvailableTypes(),
'choice_label' => function ($choice) {
return ImportEnum::getTypeName($choice);
},
))
->add('sendemail', CheckboxType::class, array(
'label' => 'Envoyé un email aux nouveaux comptes créés ?',
'required' => false,
'label_attr' => array('class' => 'checkbox-inline')
))
->add('save', SubmitType::class, ['label' => "Importer les données"]) ->add('save', SubmitType::class, ['label' => "Importer les données"])
; ;
} }
......
<?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 Version20200619102406 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('ALTER TABLE import ADD type VARCHAR(100) NOT NULL, ADD errors LONGTEXT DEFAULT NULL');
$this->addSql('ALTER TABLE prestataire DROP compte, CHANGE siret siret VARCHAR(50) DEFAULT NULL');
}
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('ALTER TABLE import DROP type, DROP errors');
$this->addSql('ALTER TABLE prestataire ADD compte NUMERIC(12, 2) NOT NULL, CHANGE siret siret VARCHAR(50) CHARACTER SET utf8 NOT NULL COLLATE `utf8_general_ci`');
}
}
<?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 Version20200619122226 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->addSql('ALTER TABLE import ADD success LONGTEXT DEFAULT NULL, ADD warnings LONGTEXT DEFAULT NULL');
$this->addSql('ALTER TABLE siege CHANGE ecompte ecompte NUMERIC(12, 2) NOT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE import DROP success, DROP warnings');
$this->addSql('ALTER TABLE siege CHANGE ecompte ecompte NUMERIC(12, 2) DEFAULT \'0.00\' NOT NULL');
}
}
<?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 Version20200619134116 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->addSql('ALTER TABLE import ADD sendemail VARCHAR(100) NOT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE import DROP sendemail');
}
}
<?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 Version20200622095500 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->addSql('ALTER TABLE import ADD nbentityadded INT DEFAULT NULL, ADD nbentityerror INT DEFAULT NULL, CHANGE errors errors LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:json)\', CHANGE success success LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:json)\', CHANGE warnings warnings LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:json)\'');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE import DROP nbentityadded, DROP nbentityerror, CHANGE errors errors LONGTEXT CHARACTER SET utf8 DEFAULT NULL COLLATE `utf8_general_ci`, CHANGE success success LONGTEXT CHARACTER SET utf8 DEFAULT NULL COLLATE `utf8_general_ci`, CHANGE warnings warnings LONGTEXT CHARACTER SET utf8 DEFAULT NULL COLLATE `utf8_general_ci`');
}
}
...@@ -64,6 +64,19 @@ class AppExtension extends AbstractExtension ...@@ -64,6 +64,19 @@ class AppExtension extends AbstractExtension
]; ];
} }
public function getFilters()
{
return array(
new \Twig_SimpleFilter('json_decode', [$this, 'jsonDecode']),
new \Twig_SimpleFilter('safe_email', [$this, 'safeEmailFilter']),
);
}
public function jsonDecode($string)
{
return json_decode($string, true);
}
public function showModalGroupChoice() public function showModalGroupChoice()
{ {
if ($this->security->getUser() != null) { if ($this->security->getUser() != null) {
...@@ -157,18 +170,6 @@ class AppExtension extends AbstractExtension ...@@ -157,18 +170,6 @@ class AppExtension extends AbstractExtension
return $this->em->getRepository(Rubrique::class)->findBy(array('enabled' => true), array('name'=> 'ASC')); return $this->em->getRepository(Rubrique::class)->findBy(array('enabled' => true), array('name'=> 'ASC'));
} }
/**
* Return a list of all filters.
*
* @return array
*/
public function getFilters()
{
return [
new \Twig_SimpleFilter('safe_email', [$this, 'safeEmailFilter']),
];
}
public function getAllFlux(User $user, Request $request, $parenttype = null) public function getAllFlux(User $user, Request $request, $parenttype = null)
{ {
$query = null; $query = null;
......
...@@ -16,25 +16,56 @@ ...@@ -16,25 +16,56 @@
{{ 'Import de données'|trans }} {{ 'Import de données'|trans }}
{% endblock %} {% endblock %}
{% block sonata_admin_content_actions_wrappers %}
<div class="navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li>
<a class="sonata-action-element" href="{{ admin.generateUrl('list') }}">
<i class="fa fa-list" aria-hidden="true"></i>
{{ 'link_action_list'|trans({}, 'SonataAdminBundle') }}
</a>
</li>
</ul>
</div>
{% endblock sonata_admin_content_actions_wrappers %}
{% block navbar_title %} {% block navbar_title %}
{{ block('title') }} {{ block('title') }}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="p-4"> <div class="px-3">
<h4><u>{{ "Exemples d'importations possible (Fichiers .csv uniquement):"|trans }}</u></h4> <h3>Recommandations et instructions :</h3>
<ul>
<li>{{ "L'importation de données ne fonctionne qu'avec des fichiers .CSV, et ayant au moins les colonnes obligatoires (celle en rouge dans les fichiers d'instructions)"|trans }}</li>
<li>{{ "L'ordre des colonnes n'a pas d'importance, mais les noms des colonnes utilisés dans la première ligne du fichier CSV ne sont pas modifiable."|trans }}</li>
<li>{{ "Pour chaque type de données (groupe, comptoir, prestataire, adherent) à importer, vous pouvez télécharger des fichiers d'exemples et d'instructions .XLSX (Excel - Windows) et .NUMBERS (Mac - Numbers), mais seul un fichier .CSV peut être importé !"|trans }}</li>
<li>{{ "Les gestionnaires (de comptoir, groupe et prestataire) correspondent aux adhérents ayant accès à l'interface d'administration !"|trans }}</li>
<li>{{ "Les contacts (de comptoir, groupe et prestataire) correspondent à des informations publiques permettant de contacter les comptoirs, groupes et prestataires, ils n'ont pas de compte crée avec leur email !"|trans }}</li>
<li>{{ "Pour les comptoirs, groupes et prestataires, vous pouvez ajouter un ou plusieurs gestionnaires (gestionnaire_email1, gestionnaire_email2), un ou plusieurs contacts par défaut visible en public (contact1, contact2) et jusqu'à 10 de chaque !"|trans }}</li>
</ul>
<h3>Exemples de fichiers :</h3>
<div class='mb-5'> <div class='mb-5'>
{% for key, csvparam in csvparams %} {% 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> <h4>{{ key|capitalize }}(s) : </h4>
<p class='ml-4'><i>{{ csvparam.header }}</i></p> <p>
<p class='ml-4 mb-4'><i>{{ 'Exemple'|trans }} :</i> {{ csvparam.example }}</p> <a class='btn btn-default ml-4' target='_blank' href='{{ csvparam.filexls }}'>Instructions en .xlsx</a>
<a class='btn btn-default ml-4' target='_blank' href='{{ csvparam.filenum }}'>Instructions en .numbers</a>
<a class='btn btn-default ml-4' target='_blank' href='{{ csvparam.filecsv }}'>Exemple .csv</a>
</p>
{# <p class='ml-4'><i>{{ csvparam.header }}</i></p>
<p class='ml-4 mb-4'><i>{{ 'Exemple'|trans }} :</i> {{ csvparam.example }}</p> #}
{% endfor %} {% endfor %}
</div> </div>
{{form_start(form)}} <hr class='color-blue'/>
{{ form_start(form) }}
{{ form_row(form.type) }}
{{ form_row(form.sendemail) }}
{{ form_row(form.media) }} {{ form_row(form.media) }}
{{ form_errors(form) }}
{{ form_row(form.user) }} {{ form_row(form.user) }}
{{ form_row(form.save) }} {{ form_row(form.save) }}
{{form_end(form)}} {{ form_end(form) }}
{% if errors is defined and errors|length > 0 %} {% if errors is defined and errors|length > 0 %}
<div class='container bg-danger w-100 py-4 row'> <div class='container bg-danger w-100 py-4 row'>
......
{% trans_default_domain 'messages' %}
{% set userlogintitle = 'Créer votre mot de passe'|trans %}
{% extends "@FOSUser/layout.html.twig" %}
{% block fos_user_content %}
{{ form_start(form, { 'action': path('fos_user_resetting_reset', {'token': token}), 'attr': { 'class': 'fos_user_resetting_reset' } }) }}
{{ form_widget(form) }}
<div>
<input type="submit" value="{{ 'Valider'|trans }}" />
</div>
{{ form_end(form) }}
{% endblock fos_user_content %}
{% if admin.hasAccess('create') and admin.hasRoute('create') %}
{% if admin.subClasses is empty %}
<li>
<a class="sonata-action-element" href="{{ admin.generateUrl('create') }}">
<i class="fa fa-plus-circle" aria-hidden="true"></i>
{{ 'Importer'|trans({}, 'messages') }}
</a>
</li>
{% else %}
{% for subclass in admin.subclasses|keys %}
<li>
<a class="sonata-action-element" href="{{ admin.generateUrl('create', {'subclass': subclass}) }}">
<i class="fa fa-plus-circle" aria-hidden="true"></i>
{{ 'Importer'|trans({}, 'messages') }} {{ subclass|trans({}, admin.translationdomain) }}
</a>
</li>
{% endfor %}
{% endif %}
{% endif %}
{# templates/fieldtypes/show_json.html.twig #}
{% extends '@SonataAdmin/CRUD/base_show_field.html.twig' %}
{% block field %}
{% set valarray = value|json_decode %}
{# {{dump(valarray|raw)}} #}
{# {{ value|json_decode|raw }} #}
<p><em>( La ligne 1 est ignorée, elle contient le nom des colonnes )</em></p>
{% for key, val in valarray %}
<p><strong>Ligne {{key}}</strong></p>
<ul>
{% for key2, val2 in val %}
<li>Colonne "{{key2}}" <ul><li>{{val2}}</li></ul></li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}
\ No newline at end of file
...@@ -9,10 +9,11 @@ ...@@ -9,10 +9,11 @@
<h2 style="font-size: 18px; color: #111111; font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; font-weight: bold; line-height: 1.2em; margin: 40px 0 10px;">{{ 'Valider la création de votre compte'|trans }}</h2><br/> <h2 style="font-size: 18px; color: #111111; font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; font-weight: bold; line-height: 1.2em; margin: 40px 0 10px;">{{ 'Valider la création de votre compte'|trans }}</h2><br/>
<p> <p>
{{ 'Un administreur a crée votre nouveau compte MLC'|trans }} {{ 'Un administreur a crée votre nouveau compte MLC'|trans }}
{{ user.commonname|title }} {{ user.name|title }}
</p> </p>
<p> <p>
{{ 'Pour valider votre nouveau compte, cliquez '|trans }}<a href='{{confirmationUrl}}'>{{ 'ICI'|trans }}</a> {{ 'Pour valider votre nouveau compte, cliquez sur ce lien : '|trans }}<br/>
<a href='{{confirmationUrl}}'>{{confirmationUrl}}</a>
</p> </p>
{% endblock %} {% endblock %}
\ No newline at end of file
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