Skip to content

Commit

Permalink
feat: auto_validation function
Browse files Browse the repository at this point in the history
- create migration alembic to create function auto_validation
  (gn_profiles.auto_validation)
- create task celery in validation module
- add parameters in validation toml config

[Refs_ticket] PnX-SI#2600
Reviewed-by: andriacap
  • Loading branch information
andriacap committed Dec 12, 2023
1 parent 85d6931 commit 87d0886
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 21 deletions.
15 changes: 15 additions & 0 deletions backend/geonature/core/gn_commons/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,21 @@ class TValidations(DB.Model):
overlaps="nomenclature_valid_status", # overlaps expected
)

def auto_validation(fct_auto_validation):
stmt = f"""
select routine_name, routine_schema
from information_schema.routines
where routine_name= '{fct_auto_validation}'
and routine_type='FUNCTION';
"""
result = DB.session.execute(stmt).fetchall()
if len(result) == 0:
return
stmt_auto_validation = f"SELECT gn_profiles.{fct_auto_validation}()"
list_synthese_updated = DB.session.execute(stmt_auto_validation).fetchall()[0]
# DB.session.query(func.gn_profiles.fct_auto_validation())
return list_synthese_updated


last_validation_query = (
select(TValidations)
Expand Down
1 change: 1 addition & 0 deletions backend/geonature/core/gn_commons/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from geonature.core.gn_permissions.decorators import login_required
from geonature.core.gn_permissions.tools import get_scope
import geonature.core.gn_commons.tasks # noqa: F401
import gn_module_validation.tasks

from shapely.geometry import shape
from geoalchemy2.shape import from_shape
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
"""add_fct_auto_validation
Revision ID: 9a4b4b6f8fe6
Revises: 446e902a14e7
Create Date: 2023-10-25 17:18:04.438706
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "9a4b4b6f8fe6"
down_revision = "446e902a14e7"
branch_labels = None
depends_on = None

schema = "gn_profiles"
fct_name = "fct_auto_validation"


def upgrade():
op.execute(
f"""
create or replace function {schema}.{fct_name} (
new_validation_status varchar default 'Probable',
score int default 3
) returns integer [] language plpgsql as $function$
declare old_validation_status text := 'En attente de validation';
new_id_status_validation int := (
select tn.id_nomenclature
from ref_nomenclatures.t_nomenclatures tn
where tn.mnemonique = new_validation_status
);
old_id_status_validation int := (
select tn.id_nomenclature
from ref_nomenclatures.t_nomenclatures tn
where tn.mnemonique = old_validation_status
);
list_uuid_obs_status_updatable uuid [] := (
select array_agg(vlv.uuid_attached_row)
from gn_commons.v_latest_validation vlv
join gn_profiles.v_consistancy_data vcd on vlv.uuid_attached_row = vcd.id_sinp
and (
(
vcd.valid_phenology::int + vcd.valid_altitude::int + vcd.valid_distribution::int
) = score
)
where vlv.id_nomenclature_valid_status = old_id_status_validation
and validation_auto = true
and id_validator is null
);
list_uuid_validation_to_update uuid [] := array (
select t.uuid_attached_row
from (
select distinct on (uuid_attached_row) uuid_attached_row,
id_validation,
validation_date
from gn_commons.t_validations tv
where uuid_attached_row = any (list_uuid_obs_status_updatable)
order by uuid_attached_row,
validation_date desc
) as t
);
list_id_sythese_updated int [] := array (
select s.id_synthese
from gn_synthese.synthese s
where s.unique_id_sinp = any (list_uuid_validation_to_update)
);
_schema_name text = 'gn_commons';
_table_name text = 't_validations';
indx int;
begin if array_length(list_uuid_validation_to_update, 1) > 0 then for indx in 1..array_length(list_uuid_validation_to_update, 1) loop raise notice 'Mise à jour du status % --> %, pour l''uuid_attached_row : % dans la table %.% ( id_synthese = % )',
old_validation_status,
new_validation_status,
list_uuid_validation_to_update [indx],
_schema_name,
_table_name,
list_id_sythese_updated [indx];
execute format(
'
INSERT INTO %I.%I (uuid_attached_row, id_nomenclature_valid_status, validation_auto, id_validator, validation_comment, validation_date)
VALUES ($1, $2 ,false, null,''auto = default value'',CURRENT_TIMESTAMP)',
_schema_name,
_table_name
) using list_uuid_validation_to_update [indx],
new_id_status_validation;
end loop;
end if;
return list_id_sythese_updated;
end;
$function$;
"""
)


def downgrade():
op.execute(
f"""
DROP FUNCTION {schema}.{fct_name}
"""
)
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@ class GnModuleSchemaConf(Schema):
MAIL_BODY = fields.String(load_default=MAIL_BODY)
MAIL_SUBJECT = fields.String(load_default=MAIL_SUBJECT)
COLUMN_LIST = fields.List(fields.Nested(ColumnSchema), load_default=COLUMN_LIST)
AUTO_VALIDATION_CRONTAB = fields.String(load_default="* 1 * * *")
AUTO_VALIDATION_ENABLED = fields.Boolean(load_default=False)
AUTO_VALIDATION_SQL_FUNCTION = fields.String(load_default="fct_auto_validation")

39 changes: 39 additions & 0 deletions contrib/gn_module_validation/backend/gn_module_validation/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from celery.schedules import crontab
from celery.utils.log import get_task_logger

from geonature.core.gn_commons.models import TValidations
from geonature.utils.celery import celery_app
from geonature.utils.config import config

logger = get_task_logger(__name__)


@celery_app.on_after_finalize.connect
def setup_periodic_tasks(sender, **kwargs):
is_enabled = config["VALIDATION"]["AUTO_VALIDATION_ENABLED"]
ct = config["VALIDATION"]["AUTO_VALIDATION_CRONTAB"]
if ct and is_enabled:
minute, hour, day_of_month, month_of_year, day_of_week = ct.split(" ")
sender.add_periodic_task(
crontab(
minute=minute,
hour=hour,
day_of_week=day_of_week,
day_of_month=day_of_month,
month_of_year=month_of_year,
),
set_auto_validation.s(),
name="auto validation",
)


@celery_app.task(bind=True)
def set_auto_validation(self):
is_enabled = config["VALIDATION"]["AUTO_VALIDATION_ENABLED"]
fct_auto_validation_name = config["VALIDATION"]['AUTO_VALIDATION_SQL_FUNCTION']
if is_enabled:
logger.info("Set autovalidation...")
TValidations.auto_validation(fct_auto_validation_name)
logger.info("Auto validation done")


1 change: 1 addition & 0 deletions contrib/gn_module_validation/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"blueprint = gn_module_validation.blueprint:blueprint",
"config_schema = gn_module_validation.conf_schema_toml:GnModuleSchemaConf",
"migrations = gn_module_validation:migrations",
"tasks = gn_module_validation.tasks",
],
},
classifiers=[
Expand Down
27 changes: 6 additions & 21 deletions contrib/gn_module_validation/validation_config.toml.example
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
[[COLUMN_LIST]]
column_label = "Taxon"
column_name = "taxref.nom_vern_or_lb_nom"
min_width = 250
# PARAMETRES CONFIG MODULE VALIDATION

[[COLUMN_LIST]]
column_label = "Date obs"
column_name = "date_min"
min_width = 100
# FONCTION AUTO_VALIDATION A SURCOUCHER SI LA FONCTION DE BASE N'EST PAS ADAPATEE A VOTRE CAS D'USAGE

[[COLUMN_LIST]]
column_label = "Jeu de données"
column_name = "dataset.dataset_name"
max_width = 100

[[COLUMN_LIST]]
column_label = "Observateur"
column_name = "observers"
min_width = 100
#AUTO_VALIDATION_CRONTAB = "* 1 * * *"
#AUTO_VALIDATION_ENABLED = true

# Exemple d’ajout d’une colonne supplémentaire
#[[COLUMN_LIST]]
#column_label = "Stade de vie"
#column_name = "nomenclature_life_stage.label_default"
#min_width = 50
## CUSTOM NAME FUNCTION AUTO VALIDATION
#AUTO_VALIDATION_SQL_FUNCTION = "fct_auto_validation"

0 comments on commit 87d0886

Please sign in to comment.