Commit f217d970 authored by Stéphane Bouvry's avatar Stéphane Bouvry
Browse files

HOTFIX :

 - Taille du champ pour les symboles monétaires étendue à 4
 - Export des versements au format XLS (Excel)
 - Export des activités au format XLS/CSV (choix)
 - Import : Les personnes ayant un nom de famille contenant des espaces sont maintenant correctement importées
 - Import : Les entrées personnes/organisations vides sont ignorées
 - Import : La sortie affiche les personnes/organisations créées
 - Vue Projet : La vue projet permet d'afficher les projets ne contenant pas d'activité
 - DOC TECHNIQUE : La documentation sur le Regex du PFI a été mis à jour pour souligner le rôle de cette dernière dans la recherche (A lire)
 - Liste des activités : La recherche dans la liste des activités a été améliorée
parents 26b2b65f da283d7f
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -4,8 +4,7 @@ La configuration métier de Oscar est placée dans le fichier `config/autoload/l


## Rappel
Techniquement,wrap
 Oscar commence par charger la configuration par défaut présente dans le fichier `config/autoload/global.php`. **Attention**, ce fichier est versionné et permet de renseigner des valeurs par défaut, **il est susceptible d'être écrasé lors d'une mise à jour et ne doit donc pas être modifié**.
Techniquement, Oscar commence par charger la configuration par défaut présente dans le fichier `config/autoload/global.php`. **Attention**, ce fichier est versionné et permet de renseigner des valeurs par défaut, **il est susceptible d'être écrasé lors d'une mise à jour et ne doit donc pas être modifié**.

Notez que toutes les valeurs présentes dans ce fichier peuvent être surchargées par celles présentes dans le fichier `local.php`, dans ce sens, elles seront largement commentées.

@@ -50,7 +49,9 @@ return array(

## Formalisme du PFI

La règle de contrôle du PFI est précisée dans la clef `oscar > validation > pfi` (Il s'agit d'une expression régulière utilisée par Oscar pour valider les donnnées non-nulles saisies dans Oscar).
La règle de contrôle du PFI est précisée dans la clef `oscar > validation > pfi` (Il s'agit d'une expression régulière utilisée par Oscar pour valider les donnnées non-nulles saisies dans Oscar et détecter les PFI saisis dans le moteur de recherche pour proposer des résultats ciblés).

**Attention** : Comme indiqué, l'expression régulière étant utilisée pour par le moteur de recherche pour trouver une activité de recherche à partir d'un PFI, les expressions régulières trop permissive posent problème. Ex : Si vous utilisez une expression tel que `/.*/mi`, n'importe quelle recherche sera detecté comme étant un PFI, donc Oscar recherchera uniquement les activités ayant pour PFI la saisie de la recherche. Assurez vous donc que ce champ est correctement renseigné. 

```php
<?php
+3 −0
Original line number Diff line number Diff line
0 uid,1 Ignored,2 Projet ACRONYME,3 Label,4 Project LABEL,5 PFI,Composante Responsable,Laboratoire1,Responsable Scientifique,Ingénieur 1,Ingénieur 2,Montant,Versement montant 1,Versement date 1,Versement date prévue 1,Versement montant 2,Versement date 2,Versement date prévue 2,Rapport financier,Date PFI,Type,Laboratoire 2,Date de signature,Versement Date 3,Versement Montant 3,Participants
R1,osef,RELATIV,Relativité restreinte,Théorie de la gravitation,EOTP201400002,Université des sciences de Berne,Olympia,Albert Einstein,Marcel Grossmann,Julie Le Carpentier,0,,,,,,,,,Concours scientifique,US Robot,,,,"Batman,Robin  "
R2,osef,RELATIV,Relativité générale,Théorie de la gravitation,EOTP201400003,Université des sciences de Berne,Université des sciences de Berlin,Albert Einstein,Marcel Grossmann,Maurice Solovine,45000,20000,2018-01-01,2018-01-01,25000,,2018-06-01,2018-04-15,2017-12-24,Concours scientifique,US Robot,2017-12-31,2020-12-31,"666,66","Spiderman, Pollux"
+3 −2
Original line number Diff line number Diff line
@@ -173,14 +173,15 @@ class ConnectorActivityCSVWithConf implements ConnectorInterface
     * @param $separator
     * @return array
     */
    private function extractArrayString( $value, $separator ){
    public function extractArrayString( $value, $separator ){
        $out = [];
        if( $separator === null ){
            $out = [trim($value)];
        } else {
            $values = explode($separator, $value);
            foreach ($values as $v) {
                $out[] = trim($v);
                $extracted = trim($v);
                if( $extracted != "" ) $out[] = trim($v);
            }
        }
        return $out;
+48 −32
Original line number Diff line number Diff line
@@ -38,11 +38,15 @@ class ConnectorActivityJSON implements ConnectorInterface
    private $entityManager;
    private $options;

    private $createdLog;


    public function __construct( array $jsonData, EntityManager $entityManager, $options = null )
    {
        $this->jsonDatas = $jsonData;
        $this->entityManager = $entityManager;
        $this->createdLog = [];

        if( $options == null ){
            $this->options = [
                "create-missing-organization"       => false,
@@ -71,7 +75,7 @@ class ConnectorActivityJSON implements ConnectorInterface

    }

    protected function getOrganizationOrCreate( $fullname ){
    protected function getOrganizationOrCreate( $fullname, ConnectorRepport $repport ){

        try {
            return $this->entityManager->getRepository(Organization::class)
@@ -87,6 +91,7 @@ class ConnectorActivityJSON implements ConnectorInterface
                $this->entityManager->persist($organization);
                $organization->setFullName($fullname);
                $this->entityManager->flush($organization);
                $repport->addadded(sprintf("ORGANIZA '%s'", $organization));
                return $organization;
            } catch (\Exception $e) {
                $error = sprintf("Impossible de créer l'organisation '%s'", $fullname);
@@ -94,6 +99,7 @@ class ConnectorActivityJSON implements ConnectorInterface
        } catch (NonUniqueResultException $e ){
            $error = sprintf("ATTENTION, l'organisation '%s' est présente dans la base en plusieurs exemplaire", $fullname);
        }
        //$this->createdLog[] = sprintf('!ORG %s', $organization);
        throw new ConnectorException($error);
    }

@@ -102,7 +108,7 @@ class ConnectorActivityJSON implements ConnectorInterface
     * @return Role
     * @throws ConnectorException
     */
    protected function getRolePersonOrCreate( $role ){
    protected function getRolePersonOrCreate( $role, ConnectorRepport $repport ){
        try {
            return $this->entityManager->getRepository(Role::class)
                ->createQueryBuilder('r')
@@ -117,13 +123,16 @@ class ConnectorActivityJSON implements ConnectorInterface
                $this->entityManager->persist($roleObj);
                $roleObj->setRoleId($role);
                $this->entityManager->flush($roleObj);
                $repport->addadded(sprintf("ROLEPERS '%s'", $roleObj));
                return $roleObj;
            } catch (\Exception $e ){
                throw new ConnectorException(sprintf("Impossible de créer le rôle (Role) '%s' : %s", $role, $e->getMessage()));
               $error = sprintf("Impossible de créer le rôle (Role) '%s' : %s", $role, $e->getMessage());
            }
        } catch (NonUniqueResultException $e){
            throw new ConnectorException(sprintf("ATTENTION ! Le rôle (Role) '%s' est présent plusieurs fois dans la base de données", $role));
            $error = sprintf("ATTENTION ! Le rôle (Role) '%s' est présent plusieurs fois dans la base de données", $role);
        }
        //$this->createdLog[] = sprintf('!ROLEPERS %s : %s', $roleObj, $error);
        throw new ConnectorException($error);
    }

    /**
@@ -131,7 +140,7 @@ class ConnectorActivityJSON implements ConnectorInterface
     * @return OrganizationRole
     * @throws ConnectorException
     */
    protected function getRoleOrganizationOrCreate( $role ){
    protected function getRoleOrganizationOrCreate( $role, ConnectorRepport $repport ){
        try {
            $roleObj =  $project = $this->entityManager->getRepository(OrganizationRole::class)->createQueryBuilder('r')
                ->where('r.label = :label')
@@ -146,17 +155,17 @@ class ConnectorActivityJSON implements ConnectorInterface
                $this->entityManager->persist($roleObj);
                $roleObj->setLabel($role);
                $this->entityManager->flush($roleObj);
                $repport->addadded(sprintf("ROLEORGA '%s'", $roleObj));
                return $roleObj;
            } catch (\Exception $e ){
                throw new ConnectorException(sprintf("Impossible de créer le rôle '%s' : %s", $role, $e->getMessage()));
                throw new ConnectorException(sprintf("Impossible de créer le rôle '%s' : %s", $role, $e->getMessage()));
            }
        } catch (NonUniqueResultException $e){
            throw new ConnectorException(sprintf("ATTENTION ! Le rôle '%s' est présent plusieurs fois dans la base de données", $role));
        }
    }

    protected function getPersonOrCreate( $personDatas ){
    protected function getPersonOrCreate( $personDatas, ConnectorRepport $repport ){
        $fullname = $personDatas['firstname']. ' ' . $personDatas['lastname'] . ($personDatas['email'] ? '<'.$personDatas['email'].'>' : '');
        try {
            return $this->entityManager->getRepository(Person::class)
@@ -175,6 +184,8 @@ class ConnectorActivityJSON implements ConnectorInterface
                    ->setLastname($personDatas['lastname'])
                    ->setEmail($personDatas['email']);
                $this->entityManager->flush($person);

                $repport->addadded(sprintf("PERSONNE '%s'", $person));
                return $person;

            } catch (\Exception $e ){
@@ -212,10 +223,10 @@ class ConnectorActivityJSON implements ConnectorInterface
                $project->setAcronym($acronym)
                    ->setLabel($label);
                $this->entityManager->flush($project);

                $repport->addadded(sprintf("Le projet '%s' a été créé", $project));
                return $project;
            } catch (\Exception $e ){
                die("PAS DE PROJET " . $e->getMessage());
                $repport->adderror(sprintf("Impossible de créé le projet '[%s] %s' : %s", $acronym, $label, $e->getMessage()));
            }

@@ -233,7 +244,7 @@ class ConnectorActivityJSON implements ConnectorInterface
     * @return DateType
     * @throws ConnectorException
     */
    protected function getMilestoneTypeOrCreate( $label ){
    protected function getMilestoneTypeOrCreate( $label, ConnectorRepport $repport ){
        try {
            // Obtention du projet si il existe
            return $this->entityManager->getRepository(DateType::class)->createQueryBuilder('d')
@@ -250,6 +261,9 @@ class ConnectorActivityJSON implements ConnectorInterface
                $this->entityManager->persist($milestoneType);
                $milestoneType->setLabel($label);
                $this->entityManager->flush($milestoneType);

                $repport->addadded(sprintf("JALOTYPE '%s'", $milestoneType));

                return $milestoneType;
            } catch (\Exception $e ){
                throw new ConnectorException(sprintf("Impossible de créé le type de jalon '%s' : %s", $label, $e->getMessage()));
@@ -340,11 +354,11 @@ class ConnectorActivityJSON implements ConnectorInterface
            if ($data->type) {

                // On tente de récupérer le type d'activité depuis la BDD
                $type = $this->getType($data->type);
                $type = $this->getType($data->type, $repport);

                // Invalid, on ignore
                if (!$type) {
                    $repport->addwarning(sprintf("Le type d'activité %s n'existe pas dans osar",
                    $repport->addwarning(sprintf("Le type d'activité %s n'existe pas dans oscar",
                            $data->type));
                }
            }
@@ -423,11 +437,11 @@ class ConnectorActivityJSON implements ConnectorInterface
            foreach( $data->organizations as $role=>$organizations ){
                try {

                    $roleObj = $this->getRoleOrganizationOrCreate( $role );
                    $roleObj = $this->getRoleOrganizationOrCreate( $role, $repport );

                    foreach( $organizations as $fullName ){
                        try {
                            $organization = $this->getOrganizationOrCreate($fullName);
                            $organization = $this->getOrganizationOrCreate($fullName, $repport);

                            if( !$activity->hasOrganization($organization, $roleObj->getLabel()) ){
                                $activityOrganization = new ActivityOrganization();
@@ -454,15 +468,13 @@ class ConnectorActivityJSON implements ConnectorInterface
                try {

                    ////////////////////////////////////////////////////////////
                    $roleObj = $this->getRolePersonOrCreate( $role );
                    $roleObj = $this->getRolePersonOrCreate( $role, $repport );


                    foreach( $persons as $fullName ){

                        $datasPerson = (new DataExtractorFullname())->extract($fullName);
                        $person = $this->getPersonOrCreate($datasPerson);


                        if( $datasPerson ) {
                            $person = $this->getPersonOrCreate($datasPerson, $repport);
                            if( !$activity->hasPerson($person, $role) ){
                                try {
                                    $personActivity = new ActivityPerson();
@@ -477,7 +489,11 @@ class ConnectorActivityJSON implements ConnectorInterface
                                    $repport->addadded(sprintf("Impossible d'ajouter %s dans %s avec le rôle %s : %s.", $fullName, $activity, $role, $e->getMessage()));
                                }
                            }
                        } else {
                            $repport->adderror(sprintf("Impossible de traiter la personne '%s'", $fullName));
                        }
                    }

                } catch( \Exception $e ){
                    $repport->addwarning(sprintf("Impossible d'ajouter la personne '%s' avec le rôle '%s' dans l'activité '%s' : %s",
                        $fullName, $role, $activity, $e->getMessage()));
@@ -487,7 +503,7 @@ class ConnectorActivityJSON implements ConnectorInterface
            ///////////////////////////////////////////////////////// MILESTONES
            foreach ( $data->milestones as $milestone ){
                try {
                    $type = $this->getMilestoneTypeOrCreate($milestone->type);
                    $type = $this->getMilestoneTypeOrCreate($milestone->type, $repport);
                    try {
                        $date = new \DateTime($milestone->date);
                    } catch (\Exception $e) {
+6 −6
Original line number Diff line number Diff line
@@ -107,42 +107,42 @@ class ConnectorRepport
    public function addnotice( $message ){
        $this->notices[] = [
            'time' => time(),
            'message' => $message
            'message' => '[.] ' . $message
        ];
    }

    public function addwarning( $message ){
        $this->warnings[] = [
            'time' => time(),
            'message' => $message
            'message' => '[~] ' . $message
        ];
    }

    public function adderror( $message ){
        $this->errors[] = [
            'time' => time(),
            'message' => $message
            'message' => '[!] ' . $message
        ];
    }

    public function addadded( $message ){
        $this->added[] = [
            'time' => time(),
            'message' => $message
            'message' => '[a] ' . $message
        ];
    }

    public function addupdated( $message ){
        $this->updated[] = [
            'time' => time(),
            'message' => $message
            'message' => '[u] ' . $message
        ];
    }

    public function addremoved( $message ){
        $this->removeds[] = [
            'time' => time(),
            'message' => $message
            'message' => '[-] ' . $message
        ];
    }

Loading