def test_notation_only_root_default_status():
    referentiel = Referentiel(root_action=make_action_referentiel())
    notation = Notation(referentiel)

    scores = notation.compute_and_get_scores()

    assert_score_with_nomenclature_id_equals(
        scores,
        "",
        points=0.0,
        percentage=0.0,
        potentiel=defaut_referentiel_root_points_value,
        referentiel_points=defaut_referentiel_root_points_value,
        referentiel_percentage=1,
    )
Exemple #2
0
def test_notation_only_root_default_status():
    # todo, do we want to keep this ?
    referentiel = Referentiel(root_action=make_action_referentiel(points=42),
                              mesure_depth=0)
    notation = Notation(referentiel)

    scores = notation.compute_and_get_scores()

    assert_score_with_nomenclature_id_equals(
        scores,
        "",
        points=0.0,
        percentage=0.0,
        potentiel=42,
        referentiel_points=42,
        referentiel_percentage=1,
    )
async def get_eci_scores(epci_id: str):
    query = ActionStatus.filter(epci_id=epci_id, latest=True)
    statuses: List[ActionStatus] = await ActionStatus_Pydantic.from_queryset(
        query)
    notation = Notation(referentiel_eci)

    for status in statuses:
        if status.action_id.startswith("economie_circulaire"):
            index = tuple(status.action_id.split("__")[-1].split("."))

            # convert the avancement set by the user to a statut for the notation engine
            notation_statut = Status.from_action_status_avancement(
                status.avancement)

            # set the status in the epci notation so the scores can be computed.
            notation.set_status(index, notation_statut)

    return notation.compute_and_get_scores()
Exemple #4
0
def test_redistribution_amongst_niveaux_on_eci():
    """Set all taches of a niveaux of an orientation as non concernée
    test it changes the niveaux sibling potentiel up."""
    from api.notation.referentiels import referentiel_eci

    notation = Notation(referentiel_eci)
    niveau_nc = ("1", "1", "1")
    orientation = ("1", "1")

    niveaux_faits = [
        index for index in notation.referentiel.indices
        if index[:-1] == orientation and index != niveau_nc
    ]

    for niveau in niveaux_faits:
        taches = [
            index for index in notation.referentiel.indices
            if index[:-1] == niveau
        ]
        for tache in taches:
            notation.set_status(tache, Status.faite)

    taches_nc = [
        index for index in notation.referentiel.indices
        if index[:-1] == niveau_nc
    ]
    for tache_nc in taches_nc:
        notation.set_status(tache_nc, Status.non_concernee)

    notation.compute()

    # assert that niveau non concerné  is worth 0
    assert notation.potentiels[niveau_nc] == 0
    for tache_nc in taches_nc:
        assert notation.potentiels[tache_nc] == 0

    # assert the niveaux faits are worth more because 1.1.1 is non concerné
    for niveau in niveaux_faits:
        assert notation.potentiels[niveau] > notation.referentiel.points[niveau]
        taches = [
            index for index in notation.referentiel.indices
            if index[:-1] == niveau
        ]
        for tache in taches:
            assert notation.potentiels[tache] > notation.referentiel.points[
                tache]

    # check totals
    orientation_taches_potentiel = sum([
        notation.potentiels[index] for index in notation.referentiel.indices
        if index[:-2] == orientation
    ])
    assert math.isclose(orientation_taches_potentiel,
                        notation.referentiel.points[orientation])
Exemple #5
0
async def get_cae_scores(epci_id: str) -> List[ActionReferentielScore]:
    query = ActionStatus.filter(epci_id=epci_id, latest=True)
    statuses: List[ActionStatus] = await ActionStatus_Pydantic.from_queryset(
        query)
    notation = Notation(referentiel_cae)

    for status in statuses:
        if get_referentiel_from_status(status) == "cae":
            index = tuple(status.action_id.split("__")[-1].split("."))

            # convert the avancement set by the user to a statut for the notation engine
            notation_statut = Status.from_action_status_avancement(
                status.avancement)

            # set the status in the epci notation so the scores can be computed.
            try:
                notation.set_status(index, notation_statut)
            except UnknownActionIndex:
                print(f"Warning - UnknownActionIndex {index}")

    return notation.compute_and_get_scores()
def test_notation_redistribution(notation: Notation):
    """In orientation 1.1.1 mark everything 'non_concernee' except 1st niveau

    So that 1st niveau is worth all the points of its parent orientation
    """
    niveaux_of_1_1_1 = notation.referentiel.children(("1", "1", "1"))
    for niveau in niveaux_of_1_1_1:
        notation.statuses[niveau] = Status.non_concernee

    notation.statuses[niveaux_of_1_1_1[0]] = Status.faite
    point_of_1_1_1 = notation.referentiel.points[("1", "1", "1")]
    notation.compute()

    # test that orientation 1.1.1 have score 100% of the points
    assert math.isclose(notation.points[("1", "1", "1")], point_of_1_1_1)

    # test that niveau 1.1.1.1 is worth the total its parent orientation.
    assert math.isclose(notation.points[("1", "1")], point_of_1_1_1)

    # test that tache 1.1.1.1 is worth the total its parent orientation.
    assert math.isclose(notation.points[("1", "1", "1", "1")], point_of_1_1_1)
Exemple #7
0
def test_potentiel_non_redistribution_on_eci():
    """Set all taches of every niveaux of an orientation as non concernée
    test it change the orientation potentiel to 0 and remove orientation points from ancestors potentiels."""
    from api.notation.referentiels import referentiel_eci

    notation = Notation(referentiel_eci)
    orientation = ("1", "1")
    axe = ("1", )
    root = ()

    niveaux = [
        index for index in notation.referentiel.indices
        if index[:-1] == orientation
    ]

    for niveau in niveaux:
        taches = [
            index for index in notation.referentiel.indices
            if index[:-1] == niveau
        ]
        for tache in taches:
            notation.set_status(tache, Status.non_concernee)

    notation.compute()

    for niveau in niveaux:
        assert notation.potentiels[niveau] == 0.0
    assert notation.potentiels[orientation] == 0.0

    assert (notation.potentiels[axe] == notation.referentiel.points[axe] -
            notation.referentiel.points[orientation])

    assert (notation.potentiels[root] == notation.referentiel.points[root] -
            notation.referentiel.points[orientation])
Exemple #8
0
def test_potentiel_redistribution_on_eci():
    """Set all taches of a niveau as non concernée,
    test it doesn't change potentiels of orientation but redistribute potentiel amongst niveaux"""
    from api.notation.referentiels import referentiel_eci

    notation = Notation(referentiel_eci)
    niveau = ("1", "1", "1")
    orientation = ("1", "1")
    axe = ("1", )
    root = ()
    taches = [
        index for index in notation.referentiel.indices if index[:-1] == niveau
    ]
    for tache in taches:
        notation.set_status(tache, Status.non_concernee)
    notation.compute()

    assert notation.potentiels[niveau] == 0.0
    siblings = [
        n for n in notation.referentiel.children(orientation) if n != niveau
    ]
    for sibling in siblings:
        assert math.isclose(
            notation.potentiels[sibling],
            notation.referentiel.points[orientation] / len(siblings),
        )
    assert notation.potentiels[orientation] == notation.referentiel.points[
        orientation]
    assert notation.potentiels[axe] == notation.referentiel.points[axe]
    assert notation.potentiels[root] == notation.referentiel.points[root]
def test_notation(notation: Notation):
    """In orientation 1.1.1 mark everything 'fait'

    So that the grand total is the same as the orientation 1.1.1 points from référentiel
    """
    niveaux_of_1_1_1 = notation.referentiel.children(("1", "1", "1"))
    for niveau in niveaux_of_1_1_1:
        notation.statuses[niveau] = Status.faite

    point_of_1_1_1 = notation.referentiel.points[("1", "1", "1")]
    notation.compute()

    # test that orientation 1.1.1 have score 100% of the points
    assert math.isclose(notation.points[("1", "1", "1")], point_of_1_1_1)

    # test that orientation 1.1.2 points is 0
    assert notation.points[("1", "1", "2")] == 0

    # test that the point of root (that is the grand total) is equal to orientation 1.1.1
    assert math.isclose(notation.points[tuple()], point_of_1_1_1)

    # everything is marked as fait in orientation so the percentatge should be 100%
    assert math.isclose(notation.percentages[("1", "1", "1")], 1.0)
Exemple #10
0
def test_potentiel_non_propagation_on_eci():
    """Set some taches of a niveau as non concernée test it doesn't change potentiels of ancestors"""
    from api.notation.referentiels import referentiel_eci

    notation = Notation(referentiel_eci)
    niveau = ("1", "1", "1")
    orientation = ("1", "1")
    axe = ("1", )
    root = ()
    taches = [
        index for index in notation.referentiel.indices if index[:-1] == niveau
    ]
    for tache in taches[1:]:
        notation.set_status(tache, Status.non_concernee)
    notation.compute()
    assert notation.potentiels[niveau] == notation.referentiel.points[niveau]
    assert notation.potentiels[orientation] == notation.referentiel.points[
        orientation]
    assert notation.potentiels[axe] == notation.referentiel.points[axe]
    assert notation.potentiels[root] == notation.referentiel.points[root]
def notation(referentiel) -> Notation:
    return Notation(referentiel)
Exemple #12
0
def test_notation_non_concernee_changes_parents_potentiels():
    """
    A l'intérieur d'une mesure/orientation :
    - Si une action a un statut "Non concernée", alors cette action n'est pas prise en compte pour calculer le score.
    *Exemple : Orientation 1.2. = 30 points
    Si niveau 1.2.1 dont le poids est 20% est "Non concerné" alors l'orientation 1.2 reste évaluée sur 30 points
    et le poids est reventilé sur les autres niveaux en augmentant de façon proportionnelle
        - 1.2.2 = 20% + 1/3 x 20%
        - 1.2.3 = 20% + 1/3 x 20%
        - 1.2.4 = 40% + 1/3 x 40%

    - Si toutes les actions sœurs ont un statut "Non concernée" (en dehors des mesures/orientations),
    alors le niveau parent est "Non concerné" et l'action n'est pas prise en compte pour calculer le score.
    *Exemple : Niveau 1.2.1.
    Si 1.2.1.1/2/3/4/5 sont "Non concernée" alors 1.2.1 = Non concernée*

    - Cas particulier : Si tous les enfants d'une mesure/orientation sont "Non concernée"
    alors la mesure/orientation a bien un statut "Non concernée"
    MAIS son nombre de points passe à "0" sans être reventilé sur les autres mesures/orientations.

    *Exemple : Orientation 1.2 = 30 points
    Si 1.2.1/2/3/4 = "Non concernée"
    alors 1.2 = "Non concernée" et "0/0 points" et la collectivité n'est plus évaluée sur 500 points mais sur 470 points.*
    """
    action_1_2_1 = make_action_referentiel(id_nomenclature="1.2.1",
                                           actions=[],
                                           points=25)
    action_1_2_2 = make_action_referentiel(id_nomenclature="1.2.2",
                                           actions=[],
                                           points=25)
    action_1_2_3 = make_action_referentiel(id_nomenclature="1.2.3",
                                           actions=[],
                                           points=25)
    action_1_2_4 = make_action_referentiel(id_nomenclature="1.2.4",
                                           actions=[],
                                           points=25)
    action_1_2 = make_action_referentiel(
        id_nomenclature="1.2",
        actions=[action_1_2_1, action_1_2_2, action_1_2_3, action_1_2_4],
        points=30,
    )
    action_1 = make_action_referentiel(id_nomenclature="1",
                                       actions=[action_1_2])
    action_2_2 = make_action_referentiel(
        id_nomenclature="2.2",
        actions=[],
        points=470,
    )

    action_2 = make_action_referentiel(id_nomenclature="2",
                                       actions=[action_2_2])

    root_action = make_action_referentiel(actions=[action_1, action_2])

    referentiel = Referentiel(root_action, mesure_depth=2)

    notation = Notation(referentiel)

    notation.set_status(index=("1", "2", "1"), status=Status.non_concernee)
    notation.set_status(index=("1", "2", "2"), status=Status.non_concernee)
    notation.set_status(index=("1", "2", "3"), status=Status.non_concernee)
    notation.set_status(index=("1", "2", "4"), status=Status.non_concernee)

    scores = notation.compute_and_get_scores()

    assert_score_with_nomenclature_id_equals(
        scores,
        "",
        points=0.0,
        percentage=0.0,
        potentiel=470,
        referentiel_points=500,
        referentiel_percentage=1,
    )

    assert_score_with_nomenclature_id_equals(
        scores,
        "1",
        points=0,
        percentage=0.0,
        potentiel=0,
        referentiel_points=30,
        referentiel_percentage=30 / 500,
    )

    assert_score_with_nomenclature_id_equals(
        scores,
        "1.2",
        points=0,
        percentage=0.0,
        potentiel=0,
        referentiel_points=30,
        referentiel_percentage=1,
    )

    assert_score_with_nomenclature_id_equals(
        scores,
        "1.2.1",
        points=0,
        percentage=0.0,
        potentiel=0,
        referentiel_points=30 / 4,
        referentiel_percentage=1 / 4,
    )

    assert_score_with_nomenclature_id_equals(
        scores,
        "2",
        points=0,
        percentage=0.0,
        potentiel=470,
        referentiel_points=470,
        referentiel_percentage=0.94,
    )