Commit 6b41468c authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Merge branches 'alc-agrement-duree-vie' and 'master' of...

Merge branches 'alc-agrement-duree-vie' and 'master' of https://git.unicaen.fr/open-source/OSE into alc-agrement-duree-vie

 Conflicts:
	data/ddl.php
parents f11e78ef 19694876
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
# OSE 13.0 ALPHA

## Correction de bugs

* La page de saisie des services était accessible en écrivant la bonne URL, même si le workflow ne permettait pas d'arriver à cette étape.

# OSE 12.2

## Correction de bug

* Depuis la V12, la formule de calcul ne distinguait plus si le service était effectué dans la composante d'affectation de l'intervenant ou dans une autre composante. C'est rétabli. 

# OSE 12.1

## Correction de bugs
+54 −138
Original line number Diff line number Diff line
@@ -6839,50 +6839,6 @@
        ),
      ),
    ),
    'FORMULE_TEST_STRUCTURE' => 
    array (
      'name' => 'FORMULE_TEST_STRUCTURE',
      'temporary' => false,
      'logging' => true,
      'commentaire' => 'sequence=FTEST_STRUCTURE_ID_SEQ;',
      'sequence' => 'FTEST_STRUCTURE_ID_SEQ',
      'columns' => 
      array (
        'ID' => 
        array (
          'name' => 'ID',
          'type' => 'NUMBER',
          'length' => 0,
          'scale' => '0',
          'precision' => NULL,
          'nullable' => false,
          'default' => NULL,
          'commentaire' => NULL,
        ),
        'LIBELLE' => 
        array (
          'name' => 'LIBELLE',
          'type' => 'VARCHAR2',
          'length' => 80,
          'scale' => NULL,
          'precision' => NULL,
          'nullable' => false,
          'default' => NULL,
          'commentaire' => NULL,
        ),
        'UNIVERSITE' => 
        array (
          'name' => 'UNIVERSITE',
          'type' => 'NUMBER',
          'length' => 0,
          'scale' => '0',
          'precision' => 1,
          'nullable' => false,
          'default' => '0',
          'commentaire' => NULL,
        ),
      ),
    ),
    'FORMULE_TEST_VOLUME_HORAIRE' =>
    array (
      'name' => 'FORMULE_TEST_VOLUME_HORAIRE',
@@ -16154,17 +16110,6 @@
          'default' => '1',
          'commentaire' => NULL,
        ),
        'PREMIER_RECRUTEMENT' => 
        array (
          'name' => 'PREMIER_RECRUTEMENT',
          'type' => 'NUMBER',
          'length' => 0,
          'scale' => NULL,
          'precision' => NULL,
          'nullable' => true,
          'default' => NULL,
          'commentaire' => NULL,
        ),
      ),
    ),
    'TYPE_CONTRAT' => 
@@ -17958,17 +17903,6 @@
          'default' => '0',
          'commentaire' => NULL,
        ),
        'PREMIER_RECRUTEMENT' => 
        array (
          'name' => 'PREMIER_RECRUTEMENT',
          'type' => 'NUMBER',
          'length' => 0,
          'scale' => '0',
          'precision' => 1,
          'nullable' => false,
          'default' => '0',
          'commentaire' => NULL,
        ),
      ),
    ),
    'TYPE_RESSOURCE' => 
@@ -19917,16 +19851,6 @@
        0 => 'ID',
      ),
    ),
    'FORMULE_TEST_STRUCTURE_PK' => 
    array (
      'name' => 'FORMULE_TEST_STRUCTURE_PK',
      'table' => 'FORMULE_TEST_STRUCTURE',
      'index' => 'FORMULE_TEST_STRUCTURE_PK',
      'columns' => 
      array (
        0 => 'ID',
      ),
    ),
    'FORMULE_TEST_VOLUME_HORAIRE_PK' =>
    array (
      'name' => 'FORMULE_TEST_VOLUME_HORAIRE_PK',
@@ -33737,10 +33661,10 @@ SELECT
  CASE WHEN ep.id IS NOT NULL THEN ep.taux_fi ELSE 1 END               taux_fi,
  CASE WHEN ep.id IS NOT NULL THEN ep.taux_fa ELSE 0 END               taux_fa,
  CASE WHEN ep.id IS NOT NULL THEN ep.taux_fc ELSE 0 END               taux_fc,
  s.id                                                                 structure_id,
  s.code                                                               structure_code,
  CASE WHEN COALESCE(s.id,0) = COALESCE(i.structure_id,0)      THEN 1 ELSE 0 END structure_is_affectation,
  CASE WHEN COALESCE(s.id,0) = COALESCE(to_number(p.valeur),0) THEN 1 ELSE 0 END structure_is_univ,
  str.id                                                               structure_id,
  str.code                                                             structure_code,
  CASE WHEN COALESCE(str.id,0) = COALESCE(i.structure_id,0)      THEN 1 ELSE 0 END structure_is_affectation,
  CASE WHEN COALESCE(str.id,0) = COALESCE(to_number(p.valeur),0) THEN 1 ELSE 0 END structure_is_univ,
  MAX(COALESCE( m.ponderation_service_du, 1))                          ponderation_service_du,
  MAX(COALESCE( m.ponderation_service_compl, 1))                       ponderation_service_compl,
  COALESCE(tf.service_statutaire,1)                                    service_statutaire,
@@ -33761,7 +33685,7 @@ FROM
       JOIN type_volume_horaire      tvh ON tvh.id = vh.type_volume_horaire_id
  LEFT JOIN element_pedagogique       ep ON ep.id = s.element_pedagogique_id
  LEFT JOIN structure                  s ON s.id = ep.structure_id
  LEFT JOIN structure                str ON str.id = ep.structure_id
  LEFT JOIN etape                      e ON e.id = ep.etape_id
  LEFT JOIN type_formation            tf ON tf.id = e.type_formation_id
  LEFT JOIN element_modulateur        em ON em.element_id = s.element_pedagogique_id
@@ -33776,7 +33700,7 @@ WHERE
  AND s.intervenant_id = COALESCE( OSE_FORMULE.GET_INTERVENANT_ID, s.intervenant_id )
GROUP BY
  vh.id, s.id, s.intervenant_id, ti.id, vh.type_volume_horaire_id, vhe.etat_volume_horaire_id, tvh.code,
  ep.id, ep.taux_fi, ep.taux_fa, ep.taux_fc, s.id, s.code, tf.service_statutaire, vh.heures,
  ep.id, ep.taux_fi, ep.taux_fa, ep.taux_fc, str.id, str.code, tf.service_statutaire, vh.heures,
  vh.horaire_debut, vh.horaire_fin, tis.taux_hetd_service, tis.taux_hetd_complementaire,
  ti.code, ti.taux_hetd_service, ti.taux_hetd_complementaire, i.structure_id, p.valeur
@@ -35857,6 +35781,41 @@ FROM
  privilege p
  JOIN categorie_privilege cp ON cp.id = p.categorie_id
  LEFT JOIN statuts_roles sr ON sr.privilege_id = p.id',
    ),
    'V_RECONDUCTION_CC_MODULATEUR' =>
    array (
      'name' => 'V_RECONDUCTION_CC_MODULATEUR',
      'definition' => 'CREATE OR REPLACE FORCE VIEW V_RECONDUCTION_CC_MODULATEUR AS
WITH t AS (
SELECT
  e.id                etape_id,
  e.libelle           etape_libelle,
  e.code              etape_code,
  ep.id               element_pedagogique_id,
  ccep.centre_cout_id centre_cout_id,
  em.MODULATEUR_ID    modulateur_id,
  ccep.type_heures_id type_heures_id,
  ep.annee_id         annee_id,
  ep.code             code
FROM
  etape                     e
  JOIN source               s ON s.importable = 0
  JOIN element_pedagogique ep ON ep.etape_id = e.id AND ep.histo_destruction IS NULL
  LEFT JOIN centre_cout_ep    ccep ON ccep.element_pedagogique_id = ep.id AND ccep.histo_destruction IS NULL AND ccep.source_id = s.id
  LEFT JOIN ELEMENT_MODULATEUR em ON em.ELEMENT_ID = ep.ID
WHERE
  e.histo_destruction IS NULL
)
SELECT
  t."ETAPE_ID",t."ETAPE_LIBELLE", t."ETAPE_CODE", t."ELEMENT_PEDAGOGIQUE_ID",t."CENTRE_COUT_ID", t.modulateur_id, t."TYPE_HEURES_ID",t."ANNEE_ID",t."CODE",
  ep.id new_element_pedagogique_id,
  ccep.id new_centre_cout_ep_id,
  em.id new_element_modulateur_id
FROM
  t
  LEFT JOIN element_pedagogique ep ON ep.annee_id = t.annee_id + 1 AND ep.code = t.code AND ep.histo_destruction IS NULL
  LEFT JOIN centre_cout_ep ccep ON ccep.element_pedagogique_id = ep.id AND ccep.centre_cout_id = t.centre_cout_id AND ccep.type_heures_id = t.type_heures_id
  LEFT JOIN ELEMENT_MODULATEUR em ON em.ELEMENT_ID = ep.ID',
    ),
    'V_REF_INTERVENANT' =>
    array (
@@ -44106,16 +44065,6 @@ WHERE
        2 => 'ETAT_VOLUME_HORAIRE_ID',
      ),
    ),
    'FORMULE_TEST_STRUCTURE__UN' => 
    array (
      'name' => 'FORMULE_TEST_STRUCTURE__UN',
      'table' => 'FORMULE_TEST_STRUCTURE',
      'index' => 'FORMULE_TEST_STRUCTURE__UN',
      'columns' => 
      array (
        0 => 'LIBELLE',
      ),
    ),
    'FORMULE__UN' =>
    array (
      'name' => 'FORMULE__UN',
@@ -48655,26 +48604,6 @@ END;',
        0 => 'ID',
      ),
    ),
    'FORMULE_TEST_STRUCTURE_PK' => 
    array (
      'name' => 'FORMULE_TEST_STRUCTURE_PK',
      'unique' => true,
      'table' => 'FORMULE_TEST_STRUCTURE',
      'columns' => 
      array (
        0 => 'ID',
      ),
    ),
    'FORMULE_TEST_STRUCTURE__UN' => 
    array (
      'name' => 'FORMULE_TEST_STRUCTURE__UN',
      'unique' => true,
      'table' => 'FORMULE_TEST_STRUCTURE',
      'columns' => 
      array (
        0 => 'LIBELLE',
      ),
    ),
    'FORMULE_TEST_VOLUME_HORAIRE_PK' =>
    array (
      'name' => 'FORMULE_TEST_VOLUME_HORAIRE_PK',
@@ -51305,19 +51234,6 @@ END;',
        4 => 'ANNEE_AGREMENT',
      ),
    ),
    'TBL_AGREMENT__UN_IDX' => 
    array (
      'name' => 'TBL_AGREMENT__UN_IDX',
      'unique' => true,
      'table' => 'TBL_AGREMENT',
      'columns' => 
      array (
        0 => 'TYPE_AGREMENT_ID',
        1 => 'INTERVENANT_ID',
        2 => 'STRUCTURE_ID',
        3 => 'TO_DELETE',
      ),
    ),
    'TBL_AGR_AGREMENT_FK_IDX' =>
    array (
      'name' => 'TBL_AGR_AGREMENT_FK_IDX',
+37 −9
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ use Application\Entity\Db\WfEtape;
use Application\Provider\Privilege\Privileges;
use Application\Service\Traits\CampagneSaisieServiceAwareTrait;
use Application\Service\Traits\ContextServiceAwareTrait;
use Application\Service\Traits\TypeVolumeHoraireServiceAwareTrait;
use Application\Service\Traits\ValidationServiceAwareTrait;
use Application\Service\Traits\WorkflowServiceAwareTrait;
use UnicaenAuth\Assertion\AbstractAssertion;
@@ -30,6 +31,7 @@ class ServiceAssertion extends AbstractAssertion
    use ContextServiceAwareTrait;
    use CampagneSaisieServiceAwareTrait;
    use ValidationServiceAwareTrait;
    use TypeVolumeHoraireServiceAwareTrait;



@@ -59,10 +61,12 @@ class ServiceAssertion extends AbstractAssertion
            ) { // dans ce cas ce n'est pas le WF qui agit mais on voit la validation dès qu'on a des services directement...
                // car on peut très bien avoir à visualiser cette page sans pour autant avoir de services à soi à valider!!
                return $this->assertHasServices($intervenant, $role->getStructure());
            }else if (!$this->assertEtapeAtteignable($etape, $intervenant)) {
            } else {
                if (!$this->assertEtapeAtteignable($etape, $intervenant)) {
                    return false;
                }
            }
        }

        if ($intervenant && isset($page['route'])) {
            switch ($page['route']) {
@@ -176,6 +180,8 @@ class ServiceAssertion extends AbstractAssertion
                return $this->assertImportAgenda($role);

            break;
            case 'Application\Controller\Intervenant.services':
                return $this->assertPageServices($role, $intervenant);
        }

        return true;
@@ -183,6 +189,24 @@ class ServiceAssertion extends AbstractAssertion



    protected function assertPageServices(Role $role, Intervenant $intervenant = null)
    {
        if (!$intervenant) return true;

        $typeVolumehoraireCode = $this->getMvcEvent()->getRouteMatch()->getParam('type-volume-horaire-code');
        if (!$typeVolumehoraireCode) return true;
        $typeVolumeHoraire = $this->getServiceTypeVolumeHoraire()->getByCode($typeVolumehoraireCode);

        $wfEtape = $this->getWorkflowEtape($typeVolumeHoraire, 'saisie');

        return $this->asserts([
            $this->assertIntervenant($role, $intervenant),
            $this->assertEtapeAtteignable($wfEtape, $intervenant),
        ]);
    }



    protected function assertEnseignements(Role $role)
    {
        return $this->asserts([
@@ -293,8 +317,10 @@ class ServiceAssertion extends AbstractAssertion
    {
        $services = $intervenant->getService()->filter(function (Service $service) use ($structure) {
            if (!$service->getElementPedagogique()) return false;

            return $service->getElementPedagogique()->getStructure() == $structure;
        });

        return $services->count() > 0;
    }

@@ -309,6 +335,7 @@ class ServiceAssertion extends AbstractAssertion
            );
            if (!$campagneSaisie->estOuverte()) return false;
        }

        return true;
    }

@@ -329,6 +356,7 @@ class ServiceAssertion extends AbstractAssertion
                if ($cloture && $cloture->getId()) return false; // pas de saisie si c'est clôturé
            }
        }

        return true;
    }

+26 −90
Original line number Diff line number Diff line
@@ -211,9 +211,6 @@ class OffreFormationController extends AbstractController
    public function reconductionCentreCoutAction()
    {
        $this->initFilterHistorique();
        $anneeN            = $this->getServiceContext()->getAnnee();
        $anneeN1           = $this->getServiceContext()->getAnneeSuivante();
        $fromPost          = false;
        $etapesReconduites = [];
        [$structure, $niveau, $etape] = $this->getParams();

@@ -225,41 +222,13 @@ class OffreFormationController extends AbstractController
        $this->getServiceStructure()->finderByRole($role, $qb);
        $structures = $this->getServiceStructure()->getList($qb);


        //Récupération de toutes les étapes éligibles à la reconduction des coûts
        if (!empty($structure)) {
            $etapesReconduitesResult = $this->getServiceEtape()->getEtapeReconduit($structure);
            $codesEtapesWithoutCC = [];
            if ($etapesReconduitesResult) {
                foreach ($etapesReconduitesResult as $etape) {
                    if ($etape->getAnnee()->getLibelle() == $this->getServiceContext()->getAnnee()->getLibelle()) {
                        $epWithCc = $this->getServiceElementPedagogique()->countEpWithCc($etape);
                        if(empty($epWithCc))
                        {
                            $codesEtapesWithoutCC[] = $etape->getCode();
                        }
                        $etapesReconduites[$etape->getCode()]['N']['etape']    = $etape;
                        $etapesReconduites[$etape->getCode()]['N']['epWithCc'] = $epWithCc;
                    } else {
                        $epWithCc = $this->getServiceElementPedagogique()->countEpWithCc($etape);
                        $etapesReconduites[$etape->getCode()]['N1']['etape']    = $etape;
                        $etapesReconduites[$etape->getCode()]['N1']['epWithCc'] = $epWithCc;
                    }
                }
                //Clean etapes sans aucun centre de coût
                foreach($codesEtapesWithoutCC as $code)
                {
                    unset($etapesReconduites[$code]);
                }
            }
        }

        $request = $this->getRequest();
        if ($request->isPost()) {
            $fromPost = true;

            $datas    = $request->getPost();
            //Reconduire les centres de coût des EP de l'étape.
            try {
                $etapesReconduites = $this->getServiceEtape()->getEtapeReconduit($structure);
                $etapesReconduitesCc = [];
                if (isset($datas['etapes'])) {
                    foreach ($datas['etapes'] as $code) {
@@ -269,27 +238,28 @@ class OffreFormationController extends AbstractController
                    }
                }
                $result = $this->getProcessusReconduction()->reconduireCCFormation($etapesReconduitesCc);
                if ($result > 0) {
                    $this->flashMessenger()->addSuccessMessage("Les centres de coût des éléments pédagogiques des étapes sélectionnées ont bien été reconduit pour la prochaine année universitaire ($result 
                élément(s) pédagogique(s) concerné(s))");
                } else {
                    $this->flashMessenger()->addWarningMessage("Aucun centre de cout n'a été reconduit car aucun élément
                pédagogique n'existe pour cette formation pour la prochaine année universitaire.");
                }

                $this->flashMessenger()->addSuccessMessage("Les centres de coûts des éléments pédagogiques des étapes sélectionnées ont bien été reconduit (<b>uniquement dans le cas où ils n'avaient pas encore de centre de coût paramétré pour l'année prochaine</b>). $result 
                élément(s) pédagogique(s) ont été mis à jour");


            } catch (\Exception $e) {
                $this->flashMessenger()->addErrorMessage($e->getMessage());
            }
            $fromPost = true;


        }

        if(empty($etapesReconduites) && !empty($structure))
        {
            $etapesReconduites = $this->getServiceEtape()->getEtapeReconduit($structure);
        }


        return [
            'anneeN'            => $anneeN,
            'anneeN1'           => $anneeN1,
            'structures'        => $structures,
            'structure'         => $structure,
            'etapesReconduites' => $etapesReconduites,
            'fromPost'          => $fromPost,
            'etapesReconduites' => $etapesReconduites
        ];
    }

@@ -298,54 +268,21 @@ class OffreFormationController extends AbstractController
    public function reconductionModulateurAction()
    {
        $this->initFilterHistorique();
        $anneeN  = $this->getServiceContext()->getAnnee();
        $anneeN1 = $this->getServiceContext()->getAnneeSuivante();


        [$structure, $niveau, $etape] = $this->getParams();
        $etapesReconduites = [];
        $fromPost          = 0;
        $role              = $this->getServiceContext()->getSelectedIdentityRole();



        $qb = $this->getServiceStructure()->finderByHistorique();
        $this->getServiceStructure()->finderByEnseignement($qb);
        $this->getServiceStructure()->finderByRole($role, $qb);
        $structures = $this->getServiceStructure()->getList($qb);
        $codesEtapesWithoutModulateur = [];

        //Récupération de toutes les étapes éligibles à la reconduction des coûts
        if (!empty($structure)) {
            $etapesReconduitesResult = $this->getServiceEtape()->getEtapeReconduit($structure);
            if ($etapesReconduitesResult) {
                foreach ($etapesReconduitesResult as $etape) {
                    if ($etape->getAnnee()->getLibelle() == $this->getServiceContext()->getAnnee()->getLibelle()) {
                        $epWithModulateur = $this->getServiceElementPedagogique()->countEpWithModulateur($etape);
                        if(empty($epWithModulateur))
                        {
                            $codesEtapesWithoutModulateur[] = $etape->getCode();
                        }
                        $etapesReconduites[$etape->getCode()]['N']['etape']            = $etape;
                        $etapesReconduites[$etape->getCode()]['N']['epWithModulateur'] = $epWithModulateur;
                    } else {
                        $etapesReconduites[$etape->getCode()]['N1']['etape']            = $etape;
                        $etapesReconduites[$etape->getCode()]['N1']['epWithModulateur'] = $this->getServiceElementPedagogique()->countEpWithModulateur($etape);
                    }
                }
                //Clean etapes sans aucun centre de coût
                foreach($codesEtapesWithoutModulateur as $code)
                {
                    unset($etapesReconduites[$code]);
                }
            }
        }

        $request = $this->getRequest();
        if ($request->isPost()) {
            $fromPost = true;
            $datas    = $request->getPost();
            //Reconduire les modulateurs des EP de l'étape.
            $etapesReconduites = $this->getServiceEtape()->getEtapeReconduit($structure);
            try {
                $etapesReconduitesCc = [];
                if (isset($datas['etapes'])) {
@@ -357,26 +294,25 @@ class OffreFormationController extends AbstractController
                    }
                }
                $result = $this->getProcessusReconduction()->reconduireModulateurFormation($etapesReconduitesCc);
                if ($result > 0) {
                    $this->flashMessenger()->addSuccessMessage("Les modulateurs des éléments pédagogiques des étapes sélectionnées ont bien été reconduit pour la prochaine année universitaire ($result 
                élément(s) pédagogique(s) concerné(s))");
                } else {
                    $this->flashMessenger()->addWarningMessage("Aucun modulateur n'a été reconduit car aucun élément
                pédagogique n'existe pour cette formation pour la prochaine année universitaire.");
                }

                    $this->flashMessenger()->addSuccessMessage("Les modulateurs des éléments pédagogiques des étapes sélectionnées ont bien été reconduit (<b>uniquement dans le cas où ils n'avaient pas encore de modulateur paramétré pour l'année prochaine</b>). $result 
                élément(s) pédagogique(s) ont été mis à jour");

            } catch (\Exception $e) {
                $this->flashMessenger()->addErrorMessage($e->getMessage());
            }
            $fromPost = true;
        }

        //Récupération de toutes les étapes éligibles à la reconduction des coûts
        if (empty($etapesReconduites) && !empty($structure)) {
            $etapesReconduites = $this->getServiceEtape()->getEtapeReconduit($structure);
        }


        return [
            'anneeN'            => $anneeN,
            'anneeN1'           => $anneeN1,
            'structures'        => $structures,
            'etapesReconduites' => $etapesReconduites,
            'structure'         => $structure,
            'fromPost'          => $fromPost,
        ];
    }

+100 −113

File changed.

Preview size limit exceeded, changes collapsed.

Loading