Commit 4ee144e4 by Julien Jorry

NEW : import older flux / operations from db

parent 075d59e1
......@@ -17,29 +17,35 @@ parameters:
app.import.separator: ';'
app.import.header:
groupe:
header: 'nom;description;compte'
header: 'idmlc;nom;description;compte'
example: 'Groupe local n°1;<b>Groupe local n°1</b>;123'
filecsv: '/csv/groupe.csv'
filexls: '/csv/groupe.xlsx'
filenum: '/csv/groupe.numbers'
comptoir:
header: 'groupe;nom;description;adresse;cpostal;ville;latitude;longitude;compte;contact1;phone1;email1;contact2;phone2;email2;contact3;phone3;email3'
header: 'idmlc;groupe;nom;description;adresse;cpostal;ville;latitude;longitude;compte;contact1;phone1;email1;contact2;phone2;email2;contact3;phone3;email3'
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'
filecsv: '/csv/comptoir.csv'
filexls: '/csv/comptoir.xlsx'
filenum: '/csv/comptoir.numbers'
adherent:
header: 'groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte;cotisations'
header: 'idmlc;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"'
filecsv: '/csv/adherent.csv'
filexls: '/csv/adherent.xlsx'
filenum: '/csv/adherent.numbers'
prestataire:
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'
header: 'idmlc;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;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'
filecsv: '/csv/prestataire.csv'
filexls: '/csv/prestataire.xlsx'
filenum: '/csv/prestataire.numbers'
flux:
header: 'exp_idmlc|exp;exp_type;dest_idmlc|dest;dest_type;user_email;montant;devise;date;type;moyen;reference;tauxreconversion;data'
example: '12987542;prestataire;prestamonnaielocale;prestataire;toto@toto.com;10;euro;2020-11-29 14:53;cotisation;cb;1007941234567890185;0;toto,titi,tutu...'
filecsv: '/csv/flux.csv'
filexls: '/csv/flux.xlsx'
filenum: '/csv/flux.numbers'
# SERVICES
services:
......
groupe;email;prenom;nom;phone;mobile;adresse;cpostal;ville;cotisations
Nom du groupe local (nom exact si le groupe existe déjà, sinon cela crée un nouveau groupe local !);Courriel / Email valide;Prénom;Nom de famille;Numéro de téléphone fixe;Numéro de téléphone mobile;Adresse complète;Code postal;Nom de la ville;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;10:2017,10:2018,10:2019
\ No newline at end of file
idmlc;groupe;email;prenom;nom;phone;mobile;adresse;cpostal;ville;cotisations
Identifiant unique propre à la MLC;Nom du groupe local (nom exact si le groupe existe déjà, sinon cela crée un nouveau groupe local !);Courriel / Email valide;Prénom;Nom de famille;Numéro de téléphone fixe;Numéro de téléphone mobile;Adresse complète;Code postal;Nom de la ville;Cotisations (montant:année,montant:année... => exemple : 10:2017,10,2018,10:2019)
12987542;Groupe local n°1;jean.dupont@gmail.com;Jean;Dupont;13456789;612345678;2, rue Charles de gaulle;12345;Paris;10:2017,10:2018,10:2019
\ No newline at end of file
No preview for this file type
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
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;;;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
idmlc;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
Identifiant unique propre à la MLC;Nom du groupe local (nom exact si le groupe existe déjà, sinon cela crée un nouveau groupe local !);Nom du comptoir (max 150 caractères);Description du comptoir (balisage html possible);Adresse complète (conseillé, pour la géolocalisation);Code postal;Nom de la ville;Latitude;Longitude;Compte de billet actuellement au comptoir;Email du 1er gestionnaire (obligatoire pour chaque gestionnaire !);Nom du 1er gestionnaire;Prénom du 1er gestionnaire;Téléphone fixe du 1er gestionnaire;Téléphone mobile du 1er gestionnaire;Nom du 1er contact;Téléphone du 1er contact;Email du 1er contact;Nom du 2ème contact;Téléphone du 2ème contact;Email du 2eme contact
12987542;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
\ No newline at end of file
No preview for this file type
exp_idmlc|exp;exp_type;dest_idmlc|dest;dest_type;user_email;montant;devise;date;type;moyen;reference;tauxreconversion;data
Expediteur : idmlc : identifiant unique utilisé dans les imports) ou identifiant unique utilisé sur le Kohinos en fonction du type (prestataire : raison, adhérent : email, comptoir : nom, groupe : nom);Type de l’expéditeur (Valeurs possibles : siege, groupe, comptoir, prestataire, adherent);Expediteur : idmlc : identifiant unique utilisé dans les imports) ou identifiant unique utilisé sur le Kohinos en fonction du type (prestataire : raison, adhérent : email, comptoir : nom, groupe : nom);Type du destinataire (Valeurs possibles : siege, groupe, comptoir, prestataire, adherent);Email de l’opérateur;Montant du flux;Devise du flux (Valeurs possibles : euro, mlc, emlc);Date (format : YYYY-mm-dd HH:ii);Type de flux (Valeurs possibles : achat, change, cotisation, reconversion, retrait, transaction, transfert);Moyen utilisé (Valeurs possibles : cb, espece, cheque, virement, helloasso, emlc, mlc, autre);Référence interne à la MLC de l’opération;Taux de reconversion (uniquement obligatoire si flux = reconversion);Autres informations et données (textes, tableaux et json acceptés)
12987542;prestataire;prestamonnaielocale;prestataire;toto@toto.com;10;euro;2020-11-29 14:53;cotisation;Jean Dupont;1007941234567890185;0;toto,titi,tutu…
\ No newline at end of file
nom;description;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1
Groupe local n°1;<b>Groupe local n°1</b>;123;john.doe@email.com;Doe;John;0123456789;0623456789
\ No newline at end of file
idmlc;nom;description;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1
Identifiant unique propre à la MLC;Nom du groupe local (max 150 caractères);Description du groupe (balisage html possible);Compte de billet actuellement au groupe local;Email du 1er gestionnaire (obligatoire pour chaque gestionnaire !);Nom du 1er gestionnaire;Prénom du 1er gestionnaire;Téléphone fixe du 1er gestionnaire;Téléphone mobile du 1er gestionnaire
12987542;Groupe local n°1;<b>Groupe local n°1</b>;123;john.doe@email.com;Doe;John;0123456789;0623456789
\ No newline at end of file
No preview for this file type
groupe;adresse;cpostal;ville;raison;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 (nom exact si le groupe existe déjà, sinon cela crée un nouveau 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;Horaires (non obligatoire, html);Description (html);Rubrique(s) (nom exact de celle-ci si elle existe, et séparées par une virgule si plusieurs);Liste des tags permettant de classer les prestataires (séparés par une virgule);Taux de reconversion en pourcentage (si différent pour chaque prestataire);Cotisations (montant:année,montant:année... => exemple : 10:2017,10,2018,10:2019);Email du 1er gestionnaire (obligatoire pour chaque gestionnaire !);Nom du 1er gestionnaire;Prénom du 1er gestionnaire;Téléphone fixe du 1er gestionnaire;Téléphone mobile du 1er gestionnaire;Nom du 1er contact;Téléphone du 1er contact;Email du 1er contact;Nom du 2ème contact;Téléphone du 2ème contact;Email du 2eme contact
Groupe local n°1;2, rue Charles de gaulle;12345;Paris;Nom du prestataire;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
idmlc;groupe;adresse;cpostal;ville;raison;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
Identifiant unique propre à la MLC;Nom du groupe local (nom exact si le groupe existe déjà, sinon cela crée un nouveau 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;Horaires (non obligatoire, html);Description (html);Rubrique(s) (nom exact de celle-ci si elle existe, et séparées par une virgule si plusieurs);Liste des tags permettant de classer les prestataires (séparés par une virgule);Taux de reconversion en pourcentage (si différent pour chaque prestataire);Cotisations (montant:année,montant:année... => exemple : 10:2017,10,2018,10:2019);Email du 1er gestionnaire (obligatoire pour chaque gestionnaire !);Nom du 1er gestionnaire;Prénom du 1er gestionnaire;Téléphone fixe du 1er gestionnaire;Téléphone mobile du 1er gestionnaire;Nom du 1er contact;Téléphone du 1er contact;Email du 1er contact;Nom du 2ème contact;Téléphone du 2ème contact;Email du 2eme contact
12987542;Groupe local n°1;2, rue Charles de gaulle;12345;Paris;Nom du prestataire;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
......@@ -70,6 +70,7 @@ class FluxAdmin extends AbstractAdmin
$this->trans('Moyen') => 'moyen',
$this->trans('Operateur') => 'operateur',
$this->trans('Référence') => 'reference',
$this->trans('Importé') => 'historical',
];
}
......@@ -184,5 +185,4 @@ class FluxAdmin extends AbstractAdmin
'Reference' => 'reference',
];
}
}
......@@ -55,6 +55,7 @@ class OperationAdmin extends AbstractAdmin
$this->trans('Type') => 'flux.type',
$this->trans('Moyen') => 'flux.moyen',
$this->trans('Operateur') => 'flux.operateur',
$this->trans('Importé') => 'historical',
];
}
......
......@@ -18,11 +18,14 @@ use App\Entity\Rubrique;
use App\Entity\Siege;
use App\Entity\User;
use App\Entity\Usergroup;
use App\Enum\CurrencyEnum;
use App\Enum\FluxEnum;
use App\Enum\ImportEnum;
use App\Enum\MoyenEnum;
use App\Events\MLCEvents;
use App\Form\Type\ImportFormType;
use App\Utils\CustomEntityManager;
use App\Utils\OperationFactory;
use App\Utils\OperationUtils;
use Behat\Transliterator\Transliterator;
use DateTime;
......@@ -52,6 +55,7 @@ class ImportController extends CRUDController
protected $translator;
protected $tokenGenerator;
protected $operationUtils;
protected $test;
public function __construct(CustomEntityManager $em, Security $security, UserManagerInterface $userManager, TranslatorInterface $translator, TokenGeneratorInterface $tokenGenerator, EventDispatcherInterface $eventDispatcher, OperationUtils $operationUtils)
{
......@@ -70,6 +74,7 @@ class ImportController extends CRUDController
$this->operationUtils = $operationUtils;
$this->siege = null;
$this->sendemail = false;
$this->test = false;
}
public function createAction()
......@@ -87,13 +92,16 @@ class ImportController extends CRUDController
$type = $import->getType();
$this->sendemail = (bool) $import->getSendemail();
if (!$this->test) {
// Sauvegarder l'import en base de données avant l'essai d'import
$this->em->persist($import);
$this->em->flush();
$idimport = $import->getId();
}
$this->importFromCSV($type, $media);
if (!$this->test) {
$import = $this->em->getRepository(Import::class)->findOneById($idimport);
$import->setEnabled(true);
......@@ -104,12 +112,20 @@ class ImportController extends CRUDController
$import->setNbentityerror($this->nberrors);
$this->em->persist($import);
$this->em->flush();
}
if (empty($this->errors)) {
if ($this->test) {
$this->addFlash(
'success',
'(TEST) Import effectué avec succès !'
);
} else {
$this->addFlash(
'success',
'Import effectué avec succès !'
);
}
} else {
$this->addFlash(
'error',
......@@ -149,6 +165,7 @@ class ImportController extends CRUDController
$config = $this->getParameter('app.import.header');
$result = null;
if (ImportEnum::IMPORT_ADHERENT == $type) {
$result = $this->importAdherent($csvRows);
} elseif (ImportEnum::IMPORT_PRESTATAIRE == $type) {
......@@ -157,6 +174,8 @@ class ImportController extends CRUDController
$result = $this->importGroupe($csvRows);
} elseif (ImportEnum::IMPORT_COMPTOIR == $type) {
$result = $this->importComptoir($csvRows);
} elseif (ImportEnum::IMPORT_OPERATION == $type) {
$result = $this->importOperations($csvRows);
} else {
// Ne devrait jamais arriver, mais sait-on jamais !
$this->errors['error'] = $this->translator->trans('Choisir un type de données à importer !');
......@@ -164,18 +183,50 @@ class ImportController extends CRUDController
return $result;
}
private function slugify($string)
/**
* Open and parse .CSV file.
*
* @param string $filePath Path of the file
* @param string $fileName Name of the file
* @param bool $ignoreFirstLine If true, ignore first line
*
* @return array Array of parsed values with array's key = firstline
*/
private function parseCSV($filePath, $fileName, $ignoreFirstLine = false)
{
$string = Transliterator::transliterate($string, '-');
$csv = new \SplFileObject($filePath . '/' . $fileName);
return Transliterator::urlize($string, '-');
$rows = [];
$firstline = null;
if (($handle = fopen($csv->getRealPath(), 'r')) !== false) {
$i = 0;
while (($data = fgetcsv($handle, null, ';')) !== false) {
++$i;
if (1 == $i) {
$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 !"));
++$this->nberrors;
continue;
}
$rows[] = array_combine(array_values($firstline), array_values($data));
}
}
fclose($handle);
}
return $rows;
}
private function importComptoir($csvRows)
{
// Iterate over the reader and write each row to the database
//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
//idmlc;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 = 1;
foreach ($csvRows as $row) {
if (1 == $line) {
......@@ -203,6 +254,7 @@ class ImportController extends CRUDController
++$line;
continue;
}
$idmlc = array_key_exists('idmlc', $row) ? $row['idmlc'] : '';
$description = array_key_exists('description', $row) ? $row['description'] : '';
$adresse = array_key_exists('adresse', $row) ? $row['adresse'] : '';
$cpostal = array_key_exists('cpostal', $row) ? $row['cpostal'] : '';
......@@ -216,12 +268,15 @@ class ImportController extends CRUDController
$groupeFound = new Groupe();
$groupeFound->setName($groupe);
$groupeFound->setSiege($this->siege);
if (!$this->test) {
$this->em->persist($groupeFound);
}
$this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ') . $groupe);
}
$comptoir = $this->em->getRepository(Comptoir::class)->findOneBy(['slug' => $this->slugify($nom), 'groupe' => $groupeFound]);
if (empty($comptoir)) {
$comptoir = new Comptoir();
$comptoir->setIdmlc($idmlc);
$comptoir->setGroupe($groupeFound);
$comptoir->setName($nom);
if (!empty($description)) {
......@@ -257,7 +312,10 @@ class ImportController extends CRUDController
$contactC->setName($contact);
$contactC->setTel($phone);
$contactC->setEmail($email);
if (!$this->test) {
$this->em->persist($contactC);
}
$this->addSuccess($row, $line, 'contact', $this->translator->trans('Contact ajouté : ') . $contactC);
++$cptContact;
}
......@@ -268,9 +326,11 @@ class ImportController extends CRUDController
$this->addSuccess($row, $line, 'comptoir', $this->translator->trans('Comptoir ajouté : ') . $nom);
++$this->nbsuccess;
if (!$this->test) {
$this->em->persist($comptoir);
$this->em->flush();
$this->em->clear();
}
} else {
$this->addError($row, $line, 'nom', $this->translator->trans('Le comptoir avec ce nom {name} existe déjà !', ['name' => $nom]));
++$this->nberrors;
......@@ -285,7 +345,7 @@ class ImportController extends CRUDController
private function importGroupe($csvRows)
{
// Iterate over the reader and write each row to the database
// nom;description;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1
// idmlc;nom;description;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1
$line = 1;
foreach ($csvRows as $row) {
if (1 == $line) {
......@@ -299,11 +359,19 @@ class ImportController extends CRUDController
++$line;
continue;
}
$idmlc = array_key_exists('idmlc', $row) ? $row['idmlc'] : '';
$description = array_key_exists('description', $row) ? $row['description'] : '';
$compte = array_key_exists('compte', $row) ? $row['compte'] : '';
$groupe = null;
if (!empty($idmlc)) {
$groupe = $this->em->getRepository(Groupe::class)->findOneBy(['idmlc' => $idmlc]);
}
if (empty($groupe)) {
$groupe = $this->em->getRepository(Groupe::class)->findOneBy(['slug' => $this->slugify($name)]);
}
if (empty($groupe)) {
$groupe = new Groupe();
$groupe->setIdmlc($idmlc);
$groupe->setSiege($this->em->getRepository(Siege::class)->getTheOne());
if (!empty($name)) {
$groupe->setName($name);
......@@ -326,10 +394,12 @@ class ImportController extends CRUDController
$groupe->setGestionnaires($gestionnaires);
$this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ') . $name);
$this->em->persist($groupe);
++$this->nbsuccess;
if (!$this->test) {
$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à !"));
++$this->nberrors;
......@@ -340,10 +410,15 @@ class ImportController extends CRUDController
ksort($this->warnings);
}
private function importGroupePrestataire($csvRows)
{
// @TODO
}
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;horaires;description;rubriques;tags;tauxreconversion;cotisations;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;contact1;phone1;email1;contact2;phone2;email2
// idmlc;groupe;adresse;cpostal;ville;raison;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 = 1;
foreach ($csvRows as $row) {
$hasError = false;
......@@ -396,6 +471,7 @@ class ImportController extends CRUDController
++$line;
continue;
}
$idmlc = array_key_exists('idmlc', $row) ? $row['idmlc'] : '';
$metier = array_key_exists('metier', $row) ? $row['metier'] : '';
$statut = array_key_exists('statut', $row) ? $row['statut'] : '';
$responsable = array_key_exists('responsable', $row) ? $row['responsable'] : '';
......@@ -409,9 +485,16 @@ class ImportController extends CRUDController
$tauxreconversion = array_key_exists('tauxreconversion', $row) ? $row['tauxreconversion'] : '';
$cotisations = array_key_exists('cotisations', $row) ? $row['cotisations'] : '';
$prestataire = null;
if (!empty($idmlc)) {
$prestataire = $this->em->getRepository(Prestataire::class)->findOneBy(['idmlc' => $idmlc]);
}
if (empty($prestataire)) {
$prestataire = $this->em->getRepository(Prestataire::class)->findOneBy(['slug' => $this->slugify($raison)]);
}
if (empty($prestataire)) {
$prestataire = new Prestataire();
$prestataire->setIdmlc($idmlc);
if (!empty($raison)) {
$prestataire->setRaison($raison);
......@@ -470,7 +553,10 @@ class ImportController extends CRUDController
$contactC->setName($contact);
$contactC->setTel($phone);
$contactC->setEmail($email);
if (!$this->test) {
$this->em->persist($contactC);
}
$this->addSuccess($row, $line, 'contact', $this->translator->trans('Contact ajouté : ') . $contact);
++$cptContact;
}
// Importer les gestionnaires du prestataire s'ils existent
......@@ -484,7 +570,9 @@ class ImportController extends CRUDController
$groupeFound = new Groupe();
$groupeFound->setName($groupe);
$groupeFound->setSiege($this->siege);
if (!$this->test) {
$this->em->persist($groupeFound);
}
$this->addWarning($row, $line, 'groupe', $this->translator->trans('Groupe introuvable, création du groupe : ') . $groupe);
}
$prestataire->setGroupe($groupeFound);
......@@ -515,13 +603,10 @@ class ImportController extends CRUDController
$cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]) . '0101'));
$cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]) . '1231'));
}
if (!$this->test) {
$this->em->persist($cotisation);
try {
// $this->operationUtils->executeOperations($cotisation);
$this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation(s) ajoutée(s) ligne : ') . $line);
} catch (\Exception $e) {
$this->addError($row, $line, 'cotisations', $this->translator->trans('Cotisation problème : ') . $e->getMessage());
}
$this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation(s) ajoutée(s) ligne : ') . $line);
}
}
} else {
......@@ -534,7 +619,9 @@ class ImportController extends CRUDController
if (empty($rubriqueFound)) {
$rubriqueFound = new Rubrique();
$rubriqueFound->setName($rubrique);
if (!$this->test) {
$this->em->persist($rubriqueFound);
}
$this->addSuccess($row, $line, 'rubrique', $this->translator->trans('Rubrique ajoutée : ') . $rubrique);
}
$prestataire->addRubrique($rubriqueFound);
......@@ -549,7 +636,9 @@ class ImportController extends CRUDController
if (empty($tagFound)) {
$tagFound = new EtatPrestataire();
$tagFound->setName($tag);
if (!$this->test) {
$this->em->persist($tagFound);
}
$this->addSuccess($row, $line, 'tag', $this->translator->trans('Tag ajouté : ') . $tag);
}
$prestataire->addEtat($tagFound);
......@@ -568,20 +657,24 @@ class ImportController extends CRUDController
$geolocFound->setVille($ville);
$geolocP->setGeoloc($geolocFound);
$prestataire->setGeolocs([$geolocP]);
if (!$this->test) {
$this->em->persist($geolocP);
}
}
} else {
$this->addError($row, $line, 'name', $this->translator->trans("Le prestataire avec cette raison '" . $raison . "' existe déjà !"));
$this->addError($row, $line, 'name', $this->translator->trans("Le prestataire avec cette raison '" . $raison . "' existe déjà, impossible de le réimporter !"));
++$this->nberrors;
$hasError = true;
}
if (!$hasError) {
$this->addSuccess($row, $line, 'user', $this->translator->trans('Prestataire ajouté : ') . $prestataire->__toString());
++$this->nbsuccess;
if (!$this->test) {
$this->em->persist($prestataire);
$this->em->flush();
$this->em->clear();
}
}
++$line;
}
......@@ -592,7 +685,7 @@ class ImportController extends CRUDController
private function importAdherent($csvRows)
{
// Iterate over the reader and write each row to the database
// groupe;email;prenom;nom;phone;mobile;adresse;cpostal;ville;cotisations
// idmlc;groupe;email;prenom;nom;phone;mobile;adresse;cpostal;ville;cotisations
$line = 1;
foreach ($csvRows as $row) {
$hasError = false;
......@@ -600,6 +693,7 @@ class ImportController extends CRUDController
++$line;
continue;
}
$idmlc = array_key_exists('idmlc', $row) ? $row['idmlc'] : '';
$groupe = array_key_exists('groupe', $row) ? $row['groupe'] : '';
$firstname = array_key_exists('prenom', $row) ? $row['prenom'] : '';
$lastname = array_key_exists('nom', $row) ? $row['nom'] : '';
......@@ -618,6 +712,14 @@ class ImportController extends CRUDController
continue;
}
$adherent = null;
if (!empty($idmlc)) {
$adherent = $this->em->getRepository(Adherent::class)->findOneBy(['idmlc' => $idmlc]);
}
if (empty($adherent)) {
$adherent = $this->em->getRepository(Adherent::class)->findOneBy(['email' => $email]);
}
if (empty($adherent)) {
$adherent = new Adherent();
$user = $this->userManager->createUser();
$user->setConfirmationToken($this->tokenGenerator->generateToken());
......@@ -670,7 +772,9 @@ class ImportController extends CRUDController
$groupeFound = new Groupe();
$groupeFound->setName($groupe);
$groupeFound->setSiege($this->siege);
if (!$this->test) {
$this->em->persist($groupeFound);
}
$this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ') . $groupe);
}
$adherent->setGroupe($groupeFound);
......@@ -723,6 +827,11 @@ class ImportController extends CRUDController
$geolocFound->setVille($ville);
$adherent->setGeoloc($geolocFound);
}
} else {
$this->addError($row, $line, 'email', $this->translator->trans("L'adherent avec cet email '" . $email . "' existe déjà, impossible de le réimporter !"));
++$this->nberrors;
$hasError = true;
}
if (!$hasError) {
$this->addSuccess($row, $line, 'user', $this->translator->trans('Adhérent bien ajouté ligne : ') . $line);
++$this->nbsuccess;
......@@ -734,51 +843,229 @@ class ImportController extends CRUDController
$this->em->flush();
$this->em->clear();
}
++$line;
}
ksort($this->errors);
ksort($this->warnings);
}
/**
* Open and parse .CSV file.
*
* @param string $filePath Path of the file
* @param string $fileName Name of the file
* @param bool $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 importOperations($csvRows)
{
$csv = new \SplFileObject($filePath . '/' . $fileName);
$rows = [];
$firstline = null;
if (($handle = fopen($csv->getRealPath(), 'r')) !== false) {
$i = 0;
while (($data = fgetcsv($handle, null, ';')) !== false) {
++$i;
if (1 == $i) {
$firstline = $data;
$rows[] = $data;
if ($ignoreFirstLine) {
// Iterate over the reader and write each row to the database
//exp_idmlc|exp;exp_type;dest_idmlc|dest;dest_type;user_email;montant;devise;date;type;moyen;reference;tauxreconversion;data
$line = 1;
foreach ($csvRows as $row) {
if (1 == $line) {
++$line;
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 !"));
if (!(array_key_exists('exp_idmlc', $row) || array_key_exists('exp', $row))) {
$this->addError($row, $line, 'exp_idmlc or exp', $this->translator->trans("La colonne 'exp_idmlc' ou 'exp' est obligatoire !"));
++$this->nberrors;
++$line;
continue;
}
$rows[] = array_combine(array_values($firstline), array_values($data));
if (!(array_key_exists('dest_idmlc', $row) || array_key_exists('dest', $row))) {
$this->addError($row, $line, 'dest_idmlc or dest', $this->translator->trans("La colonne 'dest_idmlc'ou 'dest' est obligatoire !"));
++$this->nberrors;
++$line;
continue;
}
if (!array_key_exists('exp_type', $row)) {
$this->addError($row, $line, 'exp_type', $this->translator->trans("La colonne 'exp_type' est obligatoire !"));
++$this->nberrors;
++$line;
continue;
}
if (!array_key_exists('dest_type', $row)) {
$this->addError($row, $line, 'dest_type', $this->translator->trans("La colonne 'dest_type' est obligatoire !"));
++$this->nberrors;
++$line;
continue;
}
fclose($handle);
if (!array_key_exists('montant', $row)) {
$this->addError($row, $line, 'montant', $this->translator->trans("La colonne 'montant' est obligatoire !"));
++$this->nberrors;
++$line;
continue;
}
if (!array_key_exists('devise', $row)) {
$this->addError($row, $line, 'devise', $this->translator->trans("La colonne 'devise' est obligatoire !"));
++$this->nberrors;
++$line;
continue;
}
if (!array_key_exists('date', $row)) {
$this->addError($row, $line, 'date', $this->translator->trans("La colonne 'date' est obligatoire !"));
++$this->nberrors;
++$line;
continue;
}
if (!array_key_exists('type', $row)) {
$this->addError($row, $line, 'type', $this->translator->trans("La colonne 'type' est obligatoire !"));
++$this->nberrors;
++$line;
continue;
}
$exp_id = array_key_exists('exp_idmlc', $row) ? $row['exp_idmlc'] : '';
$exp_name = array_key_exists('exp', $row) ? $row['exp'] : '';
$exp_type = array_key_exists('exp_type', $row) ? $row['exp_type'] : '';
$dest_id = array_key_exists('dest_idmlc', $row) ? $row['dest_idmlc'] : '';
$dest_name = array_key_exists('dest', $row) ? $row['dest'] : '';
$dest_type = array_key_exists('dest_type', $row) ? $row['dest_type'] : '';
if (!in_array($exp_type, ImportEnum::getAvailableOperators())) {
$this->addError($row, $line, 'exp_type', $this->translator->trans("La colonne 'exp_type' n'est pas valide !"));
++$this->nberrors;
++$line;
continue;
}
if (!in_array($dest_type, ImportEnum::getAvailableOperators())) {
$this->addError($row, $line, 'dest_type', $this->translator->trans("La colonne 'dest_type' n'est pas valide !"));
++$this->nberrors;
++$line;
continue;
}
$exp = $this->getEntityFromData($exp_type, $exp_id, $exp_name);
if ($exp === null) {
$this->addError($row, $line, 'exp', $this->translator->trans("L'expediteur est introuvable !"));
++$this->nberrors;
++$line;
continue;
}
$dest = $this->getEntityFromData($dest_type, $dest_id, $dest_name);
if ($dest === null) {
$this->addError($row, $line, 'dest', $this->translator->trans("Le destinataire est introuvable !"));
++$this->nberrors;
++$line;
continue;
}
$montant = $row['montant'];
if (!preg_match('/^[0-9]*([\.,][0-9]*)?$/', $montant)) {
$this->addError($row, $line, 'montant', $this->translator->trans("La colonne 'montant' est invalide !"));
++$this->nberrors;
++$line;
continue;
}
// $currency = $row['devise'];
// if (!in_array($currency, CurrencyEnum::getAvailableTypes())) {
// $this->addError($row, $line, 'currency', $this->translator->trans("La colonne 'currency' est invalide !"));
// ++$this->nberrors;
// ++$line;
// continue;
// }
$dateCsv = $row['date'];
$date = DateTime::createFromFormat('Y-m-d H:i', $dateCsv);
if (false === $date) {
$this->addError($row, $line, 'date', $this->translator->trans("La date est invalide (format attendu : 'YYYY-mm-dd HH:ii', exemple 2020-11-29 11:53) !"));
++$this->nberrors;
++$line;
continue;
}
$typeFlux = $row['type'];
if (!in_array($typeFlux, FluxEnum::getAvailableTypes())) {
$this->addError($row, $line, 'type', $this->translator->trans("Le type de flux est invalide (types attendus : ".implode(', ', FluxEnum::getAvailableTypes()).") !"));
++$this->nberrors;
++$line;
continue;
}
$moyen = $row['moyen'];
if (!in_array($moyen, MoyenEnum::getAvailableTypes())) {
$this->addError($row, $line, 'moyen', $this->translator->trans("Le moyen est invalide (moyens attendus : ".implode(', ', MoyenEnum::getAvailableTypes()).") !"));
++$this->nberrors;
++$line;
continue;
}
return $rows;
$reference = array_key_exists('reference', $row) ? $row['reference'] : '';
$tauxreconversion = array_key_exists('tauxreconversion', $row) ? $row['tauxreconversion'] : '';
$data = array_key_exists('data', $row) ? $row['data'] : '';
//@TODO : enregistrer les données passées dans flux et operation avec un flag historical
$fluxClass = FluxEnum::getClassName($typeFlux);
$flux = new $fluxClass();
$flux->setHistorical(true);
$flux->setOperateur($this->getUser());
$flux->setRole($this->getUser()->getGroups()[0]->__toString());
$flux->setExpediteur($exp);
$flux->setDestinataire($dest);
$flux->setMoyen($moyen);
$flux->setMontant($montant);
$flux->setReference($reference);
$flux->setTauxreconversion($tauxreconversion);
if (is_string($data)) {
$flux->setData([$data]);
} elseif (is_array($data)) {
$flux->setData($data);
}
if (!$this->test) {
try {
$this->em->persist($flux);
$this->em->flush();
$flux->setCreatedAt($date);
$this->em->persist($flux);
$this->em->flush();
$operations = $flux->getAllOperations($this->em);
foreach ($operations as $operation) {
$operation->setHistorical(true);
$this->em->persist($operation);
$this->em->flush();
$operation->setCreatedAt($date);
$this->em->persist($operation);
$this->em->flush();
}
} catch (Exception $e) {
$this->addError($row, $line, 'all', $this->translator->trans("L'enregistrement du flux a posé problème ! ".$e->getMessage()));
++$this->nberrors;
++$line;
continue;
}
} else {
$this->addSuccess($row, $line, 'all', $this->translator->trans('Flux ajouté : ') . $flux->__toString());
}
}
}
private function getEntityFromData(string $type, string $idmlc, string $idNameOrEmail)
{
$entity = null;
$idNameOrEmailSlug = $this->slugify($idNameOrEmail);
if ($type == 'prestataire') {
if (!empty($idNameOrEmail)) {
$entity = $this->em->getRepository(Prestataire::class)->findOneBy(['slug' => $idNameOrEmailSlug]);
} elseif (!empty($idmlc)) {
$entity = $this->em->getRepository(Prestataire::class)->findOneBy(['idmlc' => $idmlc]);
}
} elseif ($type == 'adherent') {
if (!empty($idNameOrEmail)) {
// dump($idNameOrEmail);
// exit();
$userFound = $this->em->getRepository(User::class)->findOneBy(['username' => $idNameOrEmail]);
if (!empty($userFound)) {
// $entity = $this->em->getRepository(Adherent::class)->findOneBy(['user' => $userFound->getId()]);
$entity = $userFound->getAdherent();
}
} elseif (!empty($idmlc)) {
$entity = $this->em->getRepository(Adherent::class)->findOneBy(['idmlc' => $idmlc]);
}
} elseif ($type == 'siege' && $exp_id == 'siege') {
$siege = $this->em->getRepository(Siege::class)->getTheOne();
} elseif ($type == 'groupe') {
if (!empty($idNameOrEmail)) {
$entity = $this->em->getRepository(Groupe::class)->findOneBy(['slug' => $idNameOrEmailSlug]);
} elseif (!empty($idmlc)) {
$entity = $this->em->getRepository(Groupe::class)->findOneBy(['idmlc' => $idmlc]);
}
} elseif ($type == 'comptoir') {
if (!empty($idNameOrEmail)) {
$entity = $this->em->getRepository(Comptoir::class)->findOneBy(['slug' => $idNameOrEmailSlug]);
} elseif (!empty($idmlc)) {
$entity = $this->em->getRepository(Comptoir::class)->findOneBy(['idmlc' => $idmlc]);
}
}
return $entity;
}
/**
......@@ -800,7 +1087,10 @@ class ImportController extends CRUDController
if (!empty($userFound)) {
$userFound->addPossiblegroup($groupe);
$users[] = $userFound;
if (!$this->test) {
$this->em->persist($userFound);
}
$this->addSuccess($row, $line, 'gestionnaire', $this->translator->trans('Rôle ' . $groupe . ' ajouté à l\'utilisateur ') . $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] : '';
......@@ -825,10 +1115,13 @@ class ImportController extends CRUDController
$user->setAdherent($adherent);
$adherent->setUser($user);
$users[] = $user;
$this->addSuccess($row, $line, 'gestionnaire', $this->translator->trans('Nouvel adhérent/gestionnaire' . $adherent . ' bien ajouté ligne : ') . $line);
if (!$this->test) {
$this->em->persist($user);
$this->em->persist($adherent);
$this->em->flush();
}
}
if ($this->sendemail) {
$this->eventDispatcher->dispatch(MLCEvents::REGISTRATION_ADHERENT, new UserEvent($user, $this->getRequest()));
}
......@@ -880,4 +1173,11 @@ class ImportController extends CRUDController
preg_replace('/[^0-9]/', '', substr($num, $sep + 1, strlen($num)))
);
}
private function slugify($string)
{
$string = Transliterator::transliterate($string, '-');
return Transliterator::urlize($string, '-');
}
}
......@@ -53,6 +53,14 @@ class Adherent extends AccountableObject implements AccountableInterface
protected $id;
/**
* @var string
*
* @ORM\Column(name="idmlc", type="string", length=100, nullable=true)
* @Groups({"read", "write"})
*/
protected $idmlc;
/**
* @var User
*
* @ORM\OneToOne(targetEntity="User", cascade={"all"}, mappedBy="adherent", fetch="LAZY")
......@@ -82,6 +90,27 @@ class Adherent extends AccountableObject implements AccountableInterface
return $this->id;
}
/**
* Get idmlc
* @return
*/
public function getIdmlc(): ?string
{
return $this->idmlc;
}
/**
* Set idmlc
*
* @return $this
*/
public function setIdmlc(string $idmlc): self
{
$this->idmlc = $idmlc;
return $this;
}
public function getCompte(): float
{
return $this->getEcompte();
......
......@@ -55,6 +55,14 @@ class Comptoir extends AccountableObject implements AccountableInterface
protected $id;
/**
* @var string
*
* @ORM\Column(name="idmlc", type="string", length=100, nullable=true)
* @Groups({"read", "write"})
*/
protected $idmlc;
/**
* @var \Application\Sonata\MediaBundle\Entity\Media
* @ORM\ManyToOne(targetEntity="App\Application\Sonata\MediaBundle\Entity\Media", cascade={"persist"}, fetch="LAZY")
* @ORM\JoinColumn(name="media_id", referencedColumnName="id")
......@@ -106,6 +114,27 @@ class Comptoir extends AccountableObject implements AccountableInterface
}
/**
* Get idmlc
* @return
*/
public function getIdmlc(): ?string
{
return $this->idmlc;
}
/**
* Set idmlc
*
* @return $this
*/
public function setIdmlc(string $idmlc): self
{
$this->idmlc = $idmlc;
return $this;
}
/**
* Get media.
*
* @return
......
......@@ -91,8 +91,7 @@ abstract class Flux implements FluxInterface
*
* @var string
*
* @ORM\Column(name="role", type="string", length=200)
* @Assert\NotBlank
* @ORM\Column(name="role", type="string", length=200, nullable=true)
* @Groups({"read", "write"})
*/
protected $role;
......@@ -221,6 +220,14 @@ abstract class Flux implements FluxInterface
*/
protected $operationsSiege;
/**
* @var string|null
*
* @Assert\Type("bool")
* @ORM\Column(name="historical", type="boolean", nullable=false, options={"default" : false})
*/
protected $historical;
abstract public function getParenttype(): string;
abstract public function getType(): string;
......@@ -248,6 +255,7 @@ abstract class Flux implements FluxInterface
{
$this->parenttype = $this->getParenttype();
$this->type = $this->getType();
$this->historical = false;
}
public function getId()
......@@ -514,6 +522,35 @@ abstract class Flux implements FluxInterface
return false;
}
/**
* Is historical ?
* @return boolean
*/
public function isHistorical(): bool
{
return $this->historical;
}
/**
* Get historical
* @return
*/
public function getHistorical(): bool
{
return $this->historical;
}
/**
* Set historical
* @return $this
*/
public function setHistorical($historical): self
{
$this->historical = $historical;
return $this;
}
public function getVerify()
{
if (null == $this->getHash()) {
......
......@@ -2,6 +2,7 @@
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Entity\EntityTrait\EnablableEntityTrait;
use App\Entity\EntityTrait\HasAccountsTrait;
use App\Entity\EntityTrait\HasCompteEntity;
......@@ -12,8 +13,23 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Ramsey\Uuid\Doctrine\UuidGenerator;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\MaxDepth;
/**
* @ApiResource(
* attributes={"security"="is_granted('ROLE_ADMIN_GROUPE_GERER_VIEW') or is_granted('ROLE_API')"},
* collectionOperations={
* "get"={"security"="is_granted('ROLE_ADMIN_GROUPE_GERER_LIST') or is_granted('ROLE_API')"},
* "post"={"security"="is_granted('ROLE_ADMIN_GROUPE_GERER_EDIT')"}
* },
* itemOperations={
* "get"={"security"="is_granted('ROLE_ADMIN_GROUPE_GERER_VIEW') or is_granted('ROLE_API')"},
* "put"={"security"="is_granted('ROLE_ADMIN_GROUPE_GERER_EDIT')"},
* },
* normalizationContext={"groups"={"read"}},
* denormalizationContext={"groups"={"write"}}
* )
* @ORM\Entity
* @ORM\Table(name="groupe")
* @ORM\HasLifecycleCallbacks()
......@@ -37,6 +53,14 @@ class Groupe extends AccountableObject implements AccountableInterface
protected $id;
/**
* @var string
*
* @ORM\Column(name="idmlc", type="string", length=100, nullable=true)
* @Groups({"read", "write"})
*/
protected $idmlc;
/**
* @var Siege
*
* @ORM\ManyToOne(targetEntity="Siege", inversedBy="groupes")
......@@ -122,6 +146,27 @@ class Groupe extends AccountableObject implements AccountableInterface
}
/**
* Get idmlc
* @return
*/
public function getIdmlc(): ?string
{
return $this->idmlc;
}
/**
* Set idmlc
*
* @return $this
*/
public function setIdmlc(string $idmlc): self
{
$this->idmlc = $idmlc;
return $this;
}
/**
* Set id.
*
* @param string $id [description]
......
......@@ -51,6 +51,14 @@ class Groupeprestataire
protected $id;
/**
* @var string
*
* @ORM\Column(name="idmlc", type="string", length=100, nullable=true)
* @Groups({"read", "write"})
*/
protected $idmlc;
/**
* @var string|null
*
* @ORM\Column(length=50)
......@@ -98,6 +106,27 @@ class Groupeprestataire
}
/**
* Get idmlc
* @return
*/
public function getIdmlc(): ?string
{
return $this->idmlc;
}
/**
* Set idmlc
*
* @return $this
*/
public function setIdmlc(string $idmlc): self
{
$this->idmlc = $idmlc;
return $this;
}
/**
* Get type.
*
* @return string
......
......@@ -93,9 +93,13 @@ class Import
*/
private $sendemail;
private $test;
public function __construct()
{
$this->setEnabled(false);
$this->sendemail = false;
$this->test = false;
}
public function getId()
......@@ -226,7 +230,7 @@ class Import
*
* @return
*/
public function getSendemail()
public function getSendemail(): bool
{
return $this->sendemail;
}
......@@ -236,7 +240,7 @@ class Import
*
* @return $this
*/
public function setSendemail($sendemail)
public function setSendemail(bool $sendemail): self
{
$this->sendemail = $sendemail;
......@@ -244,6 +248,26 @@ class Import
}
/**
* Get test
* @return
*/
public function getTest(): bool
{
return $this->test;
}
/**
* Set test
* @return $this
*/
public function setTest(bool $test): self
{
$this->test = $test;
return $this;
}
/**
* Get nbentityadded.
*
* @return
......
......@@ -77,6 +77,19 @@ abstract class Operation implements OperationInterface
*/
protected $hash = 'tmp';
/**
* @var string|null
*
* @Assert\Type("bool")
* @ORM\Column(name="historical", type="boolean", nullable=false, options={"default" : false})
*/
protected $historical;
public function __construct()
{
$this->historical = false;
}
public function getId()
{
return $this->id;
......@@ -215,6 +228,35 @@ abstract class Operation implements OperationInterface
}
/**
* Is historical ?
* @return boolean
*/
public function isHistorical(): bool
{
return $this->historical;
}
/**
* Get historical
* @return
*/
public function getHistorical(): bool
{
return $this->historical;
}
/**
* Set historical
* @return $this
*/
public function setHistorical($historical): self
{
$this->historical = $historical;
return $this;
}
/**
* @ORM\PostPersist
*
* @param LifecycleEventArgs $event
......
......@@ -56,6 +56,14 @@ class Prestataire extends AccountableObject implements AccountableInterface
/**
* @var string
*
* @ORM\Column(name="idmlc", type="string", length=100, nullable=true)
* @Groups({"read", "write"})
*/
protected $idmlc;
/**
* @var string
*
* @ORM\Column(name="raison", type="string", length=100)
* @Groups({"read", "write"})
*/
......@@ -321,6 +329,27 @@ class Prestataire extends AccountableObject implements AccountableInterface
return $this;
}
/**
* Get idmlc
* @return
*/
public function getIdmlc(): ?string
{
return $this->idmlc;
}
/**
* Set idmlc
*
* @return $this
*/
public function setIdmlc(string $idmlc): self
{
$this->idmlc = $idmlc;
return $this;
}
public function getSlug(): ?string
{
return $this->slug;
......
......@@ -92,7 +92,6 @@ class Reconversion extends Flux
$mlcPrestataire = $em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]);
$operations[] = OperationFactory::getOperation($this, $mlcPrestataire, CurrencyEnum::CURRENCY_EURO, $montantCommission);
// $operations[] = OperationFactory::getOperation($this, $this->getDestinataire(), CurrencyEnum::CURRENCY_EURO, $montantAVirer);
}
$operations[] = OperationFactory::getOperation($this, $this->getDestinataire(), CurrencyEnum::CURRENCY_EMLC, -$this->getMontant());
......
......@@ -2,27 +2,59 @@
namespace App\Enum;
use App\Entity\AchatMonnaie;
use App\Entity\AchatMonnaieAdherent;
use App\Entity\AchatMonnaiePrestataire;
use App\Entity\Change;
use App\Entity\ChangeAdherentComptoir;
use App\Entity\ChangePrestataireComptoir;
use App\Entity\Cotisation;
use App\Entity\CotisationAdherent;
use App\Entity\CotisationPrestataire;
use App\Entity\Reconversion;
use App\Entity\Retrait;
use App\Entity\RetraitComptoirAdherent;
use App\Entity\RetraitComptoirPrestataire;
use App\Entity\Transaction;
use App\Entity\TransactionAdherentAdherent;
use App\Entity\TransactionAdherentPrestataire;
use App\Entity\TransactionPrestataireAdherent;
use App\Entity\TransactionPrestatairePrestataire;
use App\Entity\Transfert;
use App\Entity\TransfertComptoirGroupe;
use App\Entity\TransfertGroupeComptoir;
use App\Entity\TransfertGroupeSiege;
use App\Entity\TransfertSiegeGroupe;
use App\Entity\Vente;
use App\Entity\VenteComptoirAdherent;
use App\Entity\VenteComptoirPrestataire;
use App\Entity\VenteEmlc;
use App\Entity\VenteEmlcComptoirAdherent;
use App\Entity\VenteEmlcComptoirPrestataire;
abstract class FluxEnum
{
const ACHAT_MONNAIE_ADHERENT = 'achat_monnaie_adherent';
const ACHAT_MONNAIE_PRESTATAIRE = 'achat_monnaie_prestataire';
const CHANGE_ADHERENT_COMPTOIR = 'adherent_comptoir';
const CHANGE_PRESTATAIRE_COMPTOIR = 'prestataire_comptoir';
const COTISATION_ADHERENT = 'cotisation_adherent';
const COTISATION_PRESTATAIRE = 'cotisation_prestataire';
const RECONVERSION = 'reconversion';
const RETRAIT_ADHERENT = 'retrait_adherent';
const RETRAIT_PRESTATAIRE = 'retrait_prestataire';
const TRANSACTION_ADHERENT_ADHERENT = 'adherent_adherent';
const TRANSACTION_ADHERENT_PRESTATAIRE = 'adherent_prestataire';
const TRANSACTION_PRESTATAIRE_ADHERENT = 'prestataire_adherent';
const TRANSACTION_PRESTATAIRE_PRESTATAIRE = 'prestataire_prestataire';
const TRANSFERT_COMPTOIR_GROUPE = 'comptoir_groupe';
const TRANSFERT_GROUPE_COMPTOIR = 'groupe_comptoir';
const TRANSFERT_GROUPE_SIEGE = 'groupe_siege';
const TRANSFERT_SIEGE_GROUPE = 'siege_groupe';
const VENTE_COMPTOIR_ADHERENT = 'comptoir_adherent';
const VENTE_COMPTOIR_PRESTATAIRE = 'comptoir_prestataire';
const ACHAT_MONNAIE_ADHERENT = AchatMonnaie::TYPE_ACHAT_ADHERENT;
const ACHAT_MONNAIE_PRESTATAIRE = AchatMonnaie::TYPE_ACHAT_PRESTATAIRE;
const CHANGE_ADHERENT_COMPTOIR = Change::TYPE_CHANGE_ADHERENT_COMPTOIR;
const CHANGE_PRESTATAIRE_COMPTOIR = Change::TYPE_CHANGE_PRESTATAIRE_COMPTOIR;
const COTISATION_ADHERENT = Cotisation::TYPE_COTISATION_ADHERENT;
const COTISATION_PRESTATAIRE = Cotisation::TYPE_COTISATION_PRESTATAIRE;
const RECONVERSION_PRESTATAIRE = Reconversion::TYPE_RECONVERSION_PRESTATAIRE;
const RETRAIT_ADHERENT = Retrait::TYPE_RETRAIT_ADHERENT;
const RETRAIT_PRESTATAIRE = Retrait::TYPE_RETRAIT_PRESTATAIRE;
const TRANSACTION_ADHERENT_ADHERENT = Transaction::TYPE_TRANSACTION_ADHERENT_ADHERENT;
const TRANSACTION_ADHERENT_PRESTATAIRE = Transaction::TYPE_TRANSACTION_ADHERENT_PRESTATAIRE;
const TRANSACTION_PRESTATAIRE_ADHERENT = Transaction::TYPE_TRANSACTION_PRESTATAIRE_ADHERENT;
const TRANSACTION_PRESTATAIRE_PRESTATAIRE = Transaction::TYPE_TRANSACTION_PRESTATAIRE_PRESTATAIRE;
const TRANSFERT_COMPTOIR_GROUPE = Transfert::TYPE_TRANSFERT_COMPTOIR_GROUPE;
const TRANSFERT_GROUPE_COMPTOIR = Transfert::TYPE_TRANSFERT_GROUPE_COMPTOIR;
const TRANSFERT_GROUPE_SIEGE = Transfert::TYPE_TRANSFERT_GROUPE_SIEGE;
const TRANSFERT_SIEGE_GROUPE = Transfert::TYPE_TRANSFERT_SIEGE_GROUPE;
const VENTE_COMPTOIR_ADHERENT = Vente::TYPE_VENTE_ADHERENT;
const VENTE_COMPTOIR_PRESTATAIRE = Vente::TYPE_VENTE_PRESTATAIRE;
const VENTE_EMLC_ADHERENT = VenteEmlc::TYPE_VENTE_EMLC_ADHERENT;
const VENTE_EMLC_PRESTATAIRE = VenteEmlc::TYPE_VENTE_EMLC_PRESTATAIRE;
/** @var array user friendly named type */
protected static $typeName = [
......@@ -32,7 +64,7 @@ abstract class FluxEnum
self::CHANGE_PRESTATAIRE_COMPTOIR => 'prestataire comptoir ',
self::COTISATION_ADHERENT => 'cotisation adherent ',
self::COTISATION_PRESTATAIRE => 'cotisation prestataire ',
self::RECONVERSION => 'reconversion',
self::RECONVERSION_PRESTATAIRE => 'reconversion prestataire',
self::RETRAIT_ADHERENT => 'retrait adherent ',
self::RETRAIT_PRESTATAIRE => 'retrait prestataire ',
self::TRANSACTION_ADHERENT_ADHERENT => 'adherent adherent ',
......@@ -45,6 +77,33 @@ abstract class FluxEnum
self::TRANSFERT_SIEGE_GROUPE => 'siege groupe ',
self::VENTE_COMPTOIR_ADHERENT => 'comptoir adherent ',
self::VENTE_COMPTOIR_PRESTATAIRE => 'comptoir prestataire ',
self::VENTE_EMLC_ADHERENT => 'emlc adherent',
self::VENTE_EMLC_PRESTATAIRE => 'emlc prestataire ',
];
/** @var array of classes */
protected static $className = [
self::ACHAT_MONNAIE_ADHERENT => AchatMonnaieAdherent::class,
self::ACHAT_MONNAIE_PRESTATAIRE => AchatMonnaiePrestataire::class,
self::CHANGE_ADHERENT_COMPTOIR => ChangeAdherentComptoir::class,
self::CHANGE_PRESTATAIRE_COMPTOIR => ChangePrestataireComptoir::class,
self::COTISATION_ADHERENT => CotisationAdherent::class,
self::COTISATION_PRESTATAIRE => CotisationPrestataire::class,
self::RECONVERSION_PRESTATAIRE => Reconversion::class,
self::RETRAIT_ADHERENT => RetraitComptoirAdherent::class,
self::RETRAIT_PRESTATAIRE => RetraitComptoirPrestataire::class,
self::TRANSACTION_ADHERENT_ADHERENT => TransactionAdherentAdherent::class,
self::TRANSACTION_ADHERENT_PRESTATAIRE => TransactionAdherentPrestataire::class,
self::TRANSACTION_PRESTATAIRE_ADHERENT => TransactionPrestataireAdherent::class,
self::TRANSACTION_PRESTATAIRE_PRESTATAIRE => TransactionPrestatairePrestataire::class,
self::TRANSFERT_COMPTOIR_GROUPE => TransfertComptoirGroupe::class,
self::TRANSFERT_GROUPE_COMPTOIR => TransfertGroupeComptoir::class,
self::TRANSFERT_GROUPE_SIEGE => TransfertGroupeSiege::class,
self::TRANSFERT_SIEGE_GROUPE => TransfertSiegeGroupe::class,
self::VENTE_COMPTOIR_ADHERENT => VenteComptoirAdherent::class,
self::VENTE_COMPTOIR_PRESTATAIRE => VenteComptoirPrestataire::class,
self::VENTE_EMLC_ADHERENT => VenteEmlcComptoirAdherent::class,
self::VENTE_EMLC_PRESTATAIRE => VenteEmlcComptoirPrestataire::class,
];
/**
......@@ -62,6 +121,20 @@ abstract class FluxEnum
}
/**
* @param string $typeShortName
*
* @return string
*/
public static function getClassName($typeShortName)
{
if (!isset(static::$className[$typeShortName])) {
return "Unknown type ($typeShortName)";
}
return static::$className[$typeShortName];
}
/**
* @return array<string>
*/
public static function getAvailableTypes()
......@@ -73,7 +146,7 @@ abstract class FluxEnum
self::CHANGE_PRESTATAIRE_COMPTOIR,
self::COTISATION_ADHERENT,
self::COTISATION_PRESTATAIRE,
self::RECONVERSION,
self::RECONVERSION_PRESTATAIRE,
self::RETRAIT_ADHERENT,
self::RETRAIT_PRESTATAIRE,
self::TRANSACTION_ADHERENT_ADHERENT,
......@@ -86,6 +159,8 @@ abstract class FluxEnum
self::TRANSFERT_SIEGE_GROUPE,
self::VENTE_COMPTOIR_ADHERENT,
self::VENTE_COMPTOIR_PRESTATAIRE,
self::VENTE_EMLC_ADHERENT,
self::VENTE_EMLC_PRESTATAIRE,
];
}
}
......@@ -8,6 +8,14 @@ abstract class ImportEnum
const IMPORT_COMPTOIR = "comptoir";
const IMPORT_PRESTATAIRE = "prestataire";
const IMPORT_ADHERENT = "adherent";
const IMPORT_OPERATION = "operation";
const IMPORT_OPERATION_SIEGE = "siege";
const IMPORT_OPERATION_GROUPE = "groupe";
const IMPORT_OPERATION_COMPTOIR = "comptoir";
const IMPORT_OPERATION_PRESTATAIRE = "prestataire";
const IMPORT_OPERATION_ADHERENT = "adherent";
/** @var array user friendly named type */
protected static $typeName = [
......@@ -15,6 +23,7 @@ abstract class ImportEnum
self::IMPORT_COMPTOIR => 'Comptoir(s)',
self::IMPORT_PRESTATAIRE => 'Prestataire(s)',
self::IMPORT_ADHERENT => 'Adherent(s)',
self::IMPORT_OPERATION => 'Opération(s)',
];
/**
......@@ -39,7 +48,22 @@ abstract class ImportEnum
self::IMPORT_GROUPE,
self::IMPORT_COMPTOIR,
self::IMPORT_PRESTATAIRE,
self::IMPORT_ADHERENT
self::IMPORT_ADHERENT,
self::IMPORT_OPERATION
];
}
/**
* @return array<string>
*/
public static function getAvailableOperators()
{
return [
self::IMPORT_OPERATION_SIEGE,
self::IMPORT_OPERATION_GROUPE,
self::IMPORT_OPERATION_COMPTOIR,
self::IMPORT_OPERATION_PRESTATAIRE,
self::IMPORT_OPERATION_ADHERENT
];
}
}
......@@ -62,6 +62,11 @@ class ImportFormType extends AbstractType
'required' => false,
'label_attr' => ['class' => 'checkbox-inline'],
])
->add('test', CheckboxType::class, [
'label' => "Lancer la procédure d'import pour tester (aucun enregistrement en base de données ou mail envoyé) ?",
'required' => false,
'label_attr' => ['class' => 'checkbox-inline'],
])
->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 Version20210628101747 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 adherent ADD idmlc VARCHAR(100) NOT NULL');
$this->addSql('ALTER TABLE comptoir ADD idmlc VARCHAR(100) NOT NULL');
$this->addSql('ALTER TABLE groupe ADD idmlc VARCHAR(100) NOT NULL');
$this->addSql('ALTER TABLE groupeprestaire ADD idmlc VARCHAR(100) NOT NULL');
$this->addSql('ALTER TABLE prestataire ADD idmlc 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 adherent DROP idmlc');
$this->addSql('ALTER TABLE comptoir DROP idmlc');
$this->addSql('ALTER TABLE groupe DROP idmlc');
$this->addSql('ALTER TABLE groupeprestaire DROP idmlc');
$this->addSql('ALTER TABLE prestataire DROP idmlc');
}
}
<?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 Version20210630143300 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 flux ADD historical TINYINT(1) DEFAULT \'0\' NOT NULL');
$this->addSql('ALTER TABLE operation_adherent ADD historical TINYINT(1) DEFAULT \'0\' NOT NULL');
$this->addSql('ALTER TABLE operation_comptoir ADD historical TINYINT(1) DEFAULT \'0\' NOT NULL');
$this->addSql('ALTER TABLE operation_groupe ADD historical TINYINT(1) DEFAULT \'0\' NOT NULL');
$this->addSql('ALTER TABLE operation_prestataire ADD historical TINYINT(1) DEFAULT \'0\' NOT NULL');
$this->addSql('ALTER TABLE operation_siege ADD historical TINYINT(1) DEFAULT \'0\' NOT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE flux DROP historical');
$this->addSql('ALTER TABLE operation_adherent DROP historical');
$this->addSql('ALTER TABLE operation_comptoir DROP historical');
$this->addSql('ALTER TABLE operation_groupe DROP historical');
$this->addSql('ALTER TABLE operation_prestataire DROP historical');
$this->addSql('ALTER TABLE operation_siege DROP historical');
}
}
<?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 Version20210630151004 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 flux CHANGE role role VARCHAR(200) DEFAULT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE flux CHANGE role role VARCHAR(200) 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 Version20210701131552 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 adherent CHANGE idmlc idmlc VARCHAR(100) DEFAULT NULL');
$this->addSql('ALTER TABLE comptoir CHANGE idmlc idmlc VARCHAR(100) DEFAULT NULL');
$this->addSql('ALTER TABLE groupe CHANGE idmlc idmlc VARCHAR(100) DEFAULT NULL');
$this->addSql('ALTER TABLE groupeprestaire CHANGE idmlc idmlc VARCHAR(100) DEFAULT NULL');
$this->addSql('ALTER TABLE prestataire CHANGE idmlc idmlc VARCHAR(100) DEFAULT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE adherent CHANGE idmlc idmlc VARCHAR(100) CHARACTER SET utf8 NOT NULL COLLATE `utf8_general_ci`');
$this->addSql('ALTER TABLE comptoir CHANGE idmlc idmlc VARCHAR(100) CHARACTER SET utf8 NOT NULL COLLATE `utf8_general_ci`');
$this->addSql('ALTER TABLE groupe CHANGE idmlc idmlc VARCHAR(100) CHARACTER SET utf8 NOT NULL COLLATE `utf8_general_ci`');
$this->addSql('ALTER TABLE groupeprestaire CHANGE idmlc idmlc VARCHAR(100) CHARACTER SET utf8 NOT NULL COLLATE `utf8_general_ci`');
$this->addSql('ALTER TABLE prestataire CHANGE idmlc idmlc VARCHAR(100) CHARACTER SET utf8 NOT NULL COLLATE `utf8_general_ci`');
}
}
......@@ -38,9 +38,9 @@
<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>{{ "Pour que les accents et caractères spéciaux fonctionnent, il faut que le fichier soit enregistré avec l'encodage UTF-8. Votre tableur et/ou éditeur de texte doit vous le proposer lors de l'enregistrement du fichier !"|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>{{ "Pour que les accents et caractères spéciaux fonctionnent, il faut que le fichier soit enregistré avec l'encodage UTF-8. Votre tableur et/ou éditeur de texte doit vous le proposer lors de l'enregistrement/l'export du fichier !"|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 modifiables."|trans }}</li>
<li>{{ "Pour chaque type de données (groupe, comptoir, prestataire, adherent, flux) à 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>
......@@ -62,6 +62,7 @@
{{ form_start(form) }}
{{ form_row(form.type) }}
{{ form_row(form.sendemail) }}
{{ form_row(form.test) }}
{{ form_row(form.media) }}
{{ form_errors(form) }}
{{ form_row(form.user) }}
......
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