Commit 9ff71aa4 authored by Stephane Bouvry's avatar Stephane Bouvry
Browse files

Systeme de White/Black liste en cours

parent 7f304617
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ return array(
                        'connectorsHome',
                        'connectorConfigure',
                        'contratTypePcru',
                        'declarersList',
                        'discipline', // OK
                        'documentSections',
                        'index',
+10 −0
Original line number Diff line number Diff line
@@ -1622,6 +1622,16 @@ administration:
                route: /logs
                defaults:
                    action: logs

        # Gestion et chargement du référenciel des pays
        listdeclarers:
            type: segment
            may_terminate: true
            options:
                route: /filter-declarers-recalls
                defaults:
                    action: declarersList

        # Gestion et chargement du référenciel des pays
        countries:
            type: segment
+110 −0
Original line number Diff line number Diff line
<?php
/**
 * Created by PhpStorm.
 * User: bouvry
 * Date: 04/10/19
 * Time: 11:49
 */

namespace Oscar\Command;


use Moment\Moment;
use Oscar\Entity\Activity;
use Oscar\Entity\Authentification;
use Oscar\Entity\LogActivity;
use Oscar\Entity\Person;
use Oscar\Entity\Role;
use Oscar\Entity\WorkPackage;
use Oscar\Entity\WorkPackagePerson;
use Oscar\Formatter\TimesheetActivityPeriodFormatter;
use Oscar\Service\ConnectorService;
use Oscar\Service\OscarConfigurationService;
use Oscar\Service\OscarUserContext;
use Oscar\Service\PersonService;
use Oscar\Service\TimesheetService;
use Oscar\Utils\DateTimeUtils;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Zend\Validator\Date;

class OscarCheckDatasCommand extends OscarAdvancedCommandAbstract
{
    protected static $defaultName = 'check:datas';

    protected function configure()
    {
        $this
            ->setDescription("Informations sur les déclarants")
            ->addOption(
                'date-missing',
                null,
                InputOption::VALUE_OPTIONAL,
                'Affiche les activités avec des déclarants dont les dates sont incohérentes',
                null
            );
    }


    protected function formatActivity(array $activities): void
    {
        $headers = ['ID', 'Num', 'Project(Acronym)', 'Label', 'Start', 'End'];
        $rows = [];

        foreach ($activities as $activity) {
            $rows[] = [
                $activity->getId(),
                $activity->getOscarNum(),
                $activity->getAcronym(),
                substr($activity->getLabel(), 0, 25) . '...',
                $activity->getDateStartStr(),
                $activity->getDateEndStr()
            ];
        }

        $this->getIO()->table($headers, $rows);
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        parent::execute($input, $output);

        // Activités SANS-DATE de début/fin, mais avec les LOTS
        $nodate = $this->getProjectGrantService()
            ->getActivityRepository()
            ->getActivitiesWithWorkPackageDatesMissing();
        $error = 0;
        if(count($nodate)) {
            $error += count($nodate);
            $this->getIO()->title("Activités avec déclaration de temps, mais sans DATE");
            $this->formatActivity($nodate);
        }

        // Activités avec dates étranges
        $paradox = $this->getProjectGrantService()
            ->getActivityRepository()
            ->getActivitiesWithTimeParadox();

        if(count($paradox)) {
            $error += count($paradox);
            $this->getIO()->title("Activités avec des dates de début/fin inversées");
            $this->formatActivity($paradox);
        }


        return 1;
    }

    /**
     * @return TimesheetService
     */
    protected function getTimesheetService()
    {
        return $this->getServicemanager()->get(TimesheetService::class);
    }
}
 No newline at end of file
+27 −20
Original line number Diff line number Diff line
@@ -44,8 +44,12 @@ class OscarTimesheetDeclarerCommand extends OscarCommandAbstract
        $this
            ->setDescription("Système de relance des déclarants")
            ->addOption(self::OPT_FORCE, 'f', InputOption::VALUE_NONE, "Forcer le mode non-interactif")
            ->addOption(self::OPT_DECLARER, 'd', InputOption::VALUE_OPTIONAL, "Identifiant du déclarant")
            ->addOption(self::OPT_PERIOD, 'p', InputOption::VALUE_OPTIONAL, "Période");
            ->addOption(
                self::OPT_DECLARER,
                'd',
                InputOption::VALUE_OPTIONAL,
                "Identifiant du déclarant"
            )
        ;
    }

@@ -55,14 +59,15 @@ class OscarTimesheetDeclarerCommand extends OscarCommandAbstract

        /// OPTIONS and PARAMETERS
        $declarerId = $input->getOption(self::OPT_DECLARER);
        $declarerPeriod = $input->getOption(self::OPT_PERIOD);
        $declarerPeriod = false; //$input->getOption(self::OPT_PERIOD);

        // Récupération du déclarant
        if ($declarerId) {
            if( !$declarerPeriod )
            if (!$declarerPeriod) {
                $this->declarer($input, $output, $declarerId);
            else
                $this->declarerPeriod($input, $output, $declarerId, $declarerPeriod);
            } else {
                $this->declarer($input, $output, $declarerId, $declarerPeriod);
            }
        } else {
            $this->declarersList($input, $output);
        }
@@ -71,14 +76,16 @@ class OscarTimesheetDeclarerCommand extends OscarCommandAbstract
    /**
     * @return TimesheetService
     */
    protected function getTimesheetService(){
    protected function getTimesheetService()
    {
        return $this->getServicemanager()->get(TimesheetService::class);
    }

    /**
     * @return PersonService
     */
    protected function getPersonService(){
    protected function getPersonService()
    {
        return $this->getServicemanager()->get(PersonService::class);
    }

@@ -87,8 +94,8 @@ class OscarTimesheetDeclarerCommand extends OscarCommandAbstract
//        echo "Non-disponible";
//    }

    public function declarer( InputInterface $input, OutputInterface $output, $declarerId ){

    public function declarer(InputInterface $input, OutputInterface $output, $declarerId)
    {
        $io = new SymfonyStyle($input, $output);

        try {
@@ -98,14 +105,14 @@ class OscarTimesheetDeclarerCommand extends OscarCommandAbstract
            $periods = $this->getTimesheetService()->getPersonRecallDeclaration($declarer);

            $io->table(["Période", "Durée", "état"], $periods);

        } catch (\Exception $e) {
            $io->error('Impossible de charger le déclarant : ' . $e->getMessage());
            exit(0);
        }
    }

    public function declarersList( InputInterface $input, OutputInterface $output ){
    public function declarersList(InputInterface $input, OutputInterface $output)
    {
        $io = new SymfonyStyle($input, $output);
        $io->title("Lite des déclarants");
        try {
@@ -118,7 +125,7 @@ class OscarTimesheetDeclarerCommand extends OscarCommandAbstract
            $headers = ['ID', 'Déclarant', 'Affectation', 'Déclaration(s)'];
            $io->table($headers, $out);

            $io->comment("Entrez la commande '".self::getName()." <ID> [PERIOD]' pour afficher les détails");
            $io->comment("Entrez la commande '" . self::getName() . " -d <ID>' pour afficher les détails");
        } catch (\Exception $e) {
            $io->error($e->getMessage());
        }
+102 −161
Original line number Diff line number Diff line
@@ -35,199 +35,140 @@ use Symfony\Component\Console\Style\SymfonyStyle;
use UnicaenApp\Service\Mailer\MailerService;
use Zend\Validator\Date;

class OscarTimesheetDeclarerRecallCommand extends OscarCommandAbstract
class OscarTimesheetDeclarerRecallCommand extends OscarAdvancedCommandAbstract
{
    protected static $defaultName = 'timesheets:declarers-recall';
    protected static $defaultName = 'timesheets:declarer-recall';

    const OPT_FORCE = "force";
    const OPT_DECLARER = "declarer";
    const OPT_PERIOD = "period";
    const OPT_PROCESSDATE = "processdate";

    const ARG_ALL        = "all";
    const ARG_PERSONID = "personid";

    protected function configure()
    {
        $this
            ->setDescription("Système de relance des déclarants")
            ->addOption(self::OPT_FORCE, 'f', InputOption::VALUE_NONE, "Forcer le mode non-interactif")
            ->addOption(self::OPT_DECLARER, 'd', InputOption::VALUE_REQUIRED, "Identifiant du déclarant")
            ->addOption(self::OPT_PERIOD, 'p', InputOption::VALUE_OPTIONAL, "Période")
            ->addOption(self::OPT_PROCESSDATE, 'c', InputOption::VALUE_OPTIONAL, "Date de relance (par défaut date actuelle)")
            ->addArgument(self::ARG_ALL, InputArgument::OPTIONAL, "Déclencher pour tous les déclarants", false);
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
            ->setDescription("Relance ponctuelle d'un déclarant")
            ->addOption(
                self::OPT_PROCESSDATE,
                null,
                InputOption::VALUE_OPTIONAL,
                "Date effective du rappel",
                null
            )
            ->addOption(
                self::OPT_PERIOD,
                null,
                InputOption::VALUE_OPTIONAL,
                "Période (par défaut, période en cours)",
                null
            )
            ->addOption(
                self::OPTION_FORCE,
                null,
                InputOption::VALUE_OPTIONAL,
                "Forcer l'envoi du mail même si ça n'est pas necessaire",
                null
            )
            ->addArgument(
                self::ARG_PERSONID,
                InputArgument::OPTIONAL,
                "ID du déclarant"
            );
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $this->addOutputStyle($output);

        $io = new SymfonyStyle($input, $output);
        parent::execute($input, $output);

        // Argument ALL
        $all = $input->getArgument(self::ARG_ALL);
        $personId = $input->getArgument(self::ARG_PERSONID);

        /// OPTIONS and PARAMETERS
        $declarerLogin = $input->getOption(self::OPT_DECLARER);
        $processDate = $input->getOption(self::OPT_PROCESSDATE);

        if( $processDate ){
            $processDate = new \DateTime($processDate);
        } else {
            $processDate = new \DateTime();
        }

        $io->writeln("Date effective de la relance : <bold>". $processDate->format('D d M Y') ."</bold>");
        //die();
        $force = $input->getOption(self::OPTION_FORCE) === null;

        if( $all == false && $declarerLogin == null ){
            $io->writeln("Utiliser l'option --declarant=ID");
            $this->declarersList($input, $output);
            return;
        }
        // Période
        $period = $input->getOption(self::OPT_PERIOD);

        if( $all != 'all' ){
            try {
                $person = $this->getPersonService()->getPersonByLdapLogin($declarerLogin);
                if( !$person ){
                    throw new \Exception("Nop !");
                }
                $personId = $person->getId();

            } catch (NoResultException $e){
                $io->error("Impossible de charger la personne à partir de son identifiant de connexion : $declarerLogin");
                return;
            }
            $declarerId = $personId;
            $all = false;
        }

        $declarerPeriod = $input->getOption(self::OPT_PERIOD);
        if( !$declarerPeriod ){
            $today = date('Y-m-d');
            $time = strtotime($today);
            $final = date("Y-m-d", strtotime("-1 month", $time));
            $declarerPeriod = DateTimeUtils::getPeriodStrFromDateStr($final);
        }
        $helps = [];

        $io->writeln("Pour la période : <bold>". $declarerPeriod ."</bold>.");


        $do = false;

        if( $all == true ){
            $declarants = $this->getTimesheetService()->getDeclarers();
            $out = [];
            /** @var Person $declarer */
            foreach ($declarants['persons'] as $personId=>$datas) {
                //$io->text("Traitement pour " . $declarants)
                try {
                    $result = $this->recallDeclarer($personId, $declarerPeriod, $io, $processDate);
                } catch (\Exception $e) {
                    $io->warning($e->getMessage());
                }
            }
        if (!$period) {
            $period = null;
            $periodText = " (Période non-spécifée)";
            $helps[] = "l'option '--period=<PERIOD>' permet de spécifier la période sous la forme YYYY-MM (ou 'now' pour la période en cours)";
        } else {
            try {
                $result = $this->recallDeclarer($personId, $declarerPeriod, $io, $processDate);
            } catch (\Exception $e) {
                $io->warning($e->getMessage());
            }
        }
        $io->comment("Opération terminée");
        return;
    }
            if ($period == 'now') {
                $period = (new \DateTime())->format('Y-m');
            }
            $periodInfos = DateTimeUtils::periodBounds($period);
            $periodlabel = $periodInfos['periodLabel'];
            $periodText = " (Pour la période $periodlabel)";
        }

        if ($personId == null) {
            $this->getIO()->title("Liste des déclarants $periodText");

            $declarers = $this->getPersonService()->getPersonsByIds(
                $period == null ?
                    $this->getPersonService()->getDeclarersIds() :
                    $this->getPersonService()->getDeclarersIdsPeriod($period)
            );
            $headers = ['ID', 'Personne', 'Email', "Identifiant"];
            $rows = [];
            foreach ($declarers as $declarer) {
                $rows[] = [
                    $declarer->getId(),
                    $declarer->getDisplayName(),
                    $declarer->getEmail(),
                    $declarer->getLadapLogin()
                ];
            }
            $this->getIO()->table($headers, $rows);
            $this->getIO()->comment("Vous pouvez utiliser l'ID de la personne en fin de commande");
        } else {
            // Déclarant
            $declarer = $this->getPersonService()->getPersonById($personId, true);

            if (!$period) {
                $periods = $this->getTimesheetService()->getPeriodsPerson($declarer);
                $rows = [];
                foreach ($periods as $period) {
                    $rows[] = [$period, DateTimeUtils::periodBounds($period)['periodLabel']];
                }
                $this->getIO()->title("Périodes pour la personne $declarer");
                $headers = ["Code", "Période"];
                $this->getIO()->table($headers, $rows);
                $this->getIO()->comment("Utiliser --period=CODE_PERIOD pour déclencher le rappel");
            } else {
                $this->getIO()->title("Rappel pour $declarer $periodText");
                if ($this->getTimesheetService()->isDeclarerAtPeriod($declarer, $period)) {
                    $result = $this->getTimesheetService()->recallProcess($declarer->getId(), $period, null, $force);

                    $this->getIO()->writeln(sprintf("Infos : <bold>%s</bold>", $result['recall_info']));
                    $this->getIO()->writeln(sprintf("Temps MIN/MAX attendu : <bold>%s/%s</bold>", $result['min'], $result['max']));
                    $this->getIO()->writeln(sprintf("Temps DELCARE/ATTENDU : <bold>%s</bold> / <bold>%s</bold>", $result['total'], $result['needed']));
                    $this->getIO()->writeln(sprintf("Mail envoyé : <bold>%s</bold>", $result['mailSend'] ? 'OUI' : 'NON'));
                    $this->getIO()->writeln(sprintf("Conflit : <bold>%s</bold>", $result['hasConflict'] ? 'OUI' : 'non'));
                    $this->getIO()->writeln(sprintf("Dernière relance envoyée : <bold>%s</bold>", $result['lastSend']));
                    $this->getIO()->writeln(sprintf("Relance envoyées pour cette période : <bold>%s</bold>", $result['recalls']));

    protected function recallDeclarer($declarerId, $declarerPeriod, SymfonyStyle $io, $processDate = null)
    {
        /** @var Person $declarer */
        $declarer = $this->getPersonService()->getPersonById($declarerId);

        $result = $this->declarerPeriod($declarerId, $declarerPeriod, $processDate);
        if( $result ) {
            $io->title($result['person']);
            $io->writeln(sprintf("Message : <options=bold>%s</>", $result['message']));
            $io->writeln(sprintf("Mail ? <options=bold>%s</>", $result['needSend'] ? 'Oui' : 'Non'));
            $io->writeln(sprintf("Déclaration (heures) : <options=bold>%s/%s</>", $result['total'], $result['needed']));
            $io->writeln(sprintf("Max : <options=bold>%s</>", $result['max']));
            $io->writeln(sprintf("Min : <options=bold>%s</>", $result['min']));
            $io->writeln(sprintf("Mail requis : <options=bold>%s</>", $result['mailRequired'] ? "Oui" : "Non"));
            $io->writeln(sprintf("Mail envoyé : <options=bold>%s</>", $result['mailSend'] ? "Oui" : "Non"));
            $io->writeln(sprintf("Dernier envoi : <options=bold>%s</>", $result['lastSend']));
            $io->writeln(sprintf("Prochain envoi : <options=bold>%s</>", $result['nextSend']));
            $io->writeln(sprintf("Status : <options=bold>%s</>", $result['status']));
                } else {
                    $this->getIO()->warning("'$declarer' n'est pas déclarant pour la période '$periodlabel'");
                }
        else {
            $io->warning("Pas de données pour $declarer à la période $declarerPeriod");
            }
        return;
        }

    /**
     * @return MailingService
     */
    protected function getMailer()
    {
        return $this->getServicemanager()->get(MailingService::class);
        return 1;
    }

    /**
     * @return TimesheetService
     */
    protected function getTimesheetService(){
    protected function getTimesheetService(): TimesheetService
    {
        return $this->getServicemanager()->get(TimesheetService::class);
    }

    /**
     * @return PersonService
     */
    protected function getPersonService(){
        return $this->getServicemanager()->get(PersonService::class);
    }

    //public function declarerRecall

    public function declarerPeriod( $declarerId, $period, $processDate = null ){
        if( $processDate == null ){
            $processDate = new \DateTime();
        }
        return $this->getTimesheetService()->recallProcess($declarerId, $period, $processDate);
    }

    public function declarer( InputInterface $input, OutputInterface $output, $declarerId ){

        $io = new SymfonyStyle($input, $output);

        try {
            $declarer = $this->getPersonService()->getPerson($declarerId);

            $io->title("Système de relance pour $declarer");
            $periods = $this->getTimesheetService()->getPersonRecallDeclaration($declarer);

            $io->table(["Période", "Durée", "état"], $periods);

        } catch (\Exception $e) {
            $io->error('Impossible de charger le déclarant : ' . $e->getMessage());
            exit(0);
        }
    }

    public function declarersList( InputInterface $input, OutputInterface $output ){
        $io = new SymfonyStyle($input, $output);
        $io->title("Lite des déclarants");
        try {
            $declarants = $this->getTimesheetService()->getDeclarers();
            $out = [];
            /** @var Person $declarer */
            foreach ($declarants['persons'] as $personId=>$datas) {
                $out[] = [$personId, $datas['displayname'], $datas['login'], $datas['affectation'], count($datas['declarations'])];
            }
            $headers = ['ID', 'login', 'Déclarant', 'Affectation', 'Déclaration(s)'];
            $io->table($headers, $out);

            $io->comment("Entrez la commande '".self::getName()." --". self::OPT_DECLARER . "=<ID>' pour afficher les détails");
        } catch (\Exception $e) {
            $io->error($e->getMessage());
        }
    }
}
 No newline at end of file
Loading