diff --git a/apptax/migrations/versions/dbb7d939fef0_herited_attributes.py b/apptax/migrations/versions/dbb7d939fef0_herited_attributes.py new file mode 100644 index 00000000..2cdbad6c --- /dev/null +++ b/apptax/migrations/versions/dbb7d939fef0_herited_attributes.py @@ -0,0 +1,85 @@ +""" Create herited attributes view + +Revision ID: dbb7d939fef0 +Revises: 4fb7e197d241 +Create Date: 2021-09-28 11:49:57.654351 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'dbb7d939fef0' +down_revision = '4fb7e197d241' +branch_labels = None +depends_on = None + + +def upgrade(): + op.execute(""" + CREATE MATERIALIZED VIEW taxonomie.taxref_tree + AS WITH RECURSIVE x AS ( + SELECT t.cd_nom as cd_ref, + t.cd_nom::text::ltree AS path + FROM taxonomie.taxref t + WHERE t.cd_sup IS NULL AND t.cd_nom = t.cd_ref + UNION ALL + SELECT y.cd_nom AS cd_ref, + ltree_addtext(x_1.path, y.cd_nom::text) AS path + FROM x x_1, + taxonomie.taxref y + WHERE y.cd_nom = y.cd_ref AND x_1.cd_ref = y.cd_sup + ) + SELECT x.cd_ref, + x.path + FROM x + WITH DATA; + + -- View indexes: + CREATE UNIQUE INDEX taxref_tree_cd_nom_idx ON taxonomie.taxref_tree USING btree (cd_ref); + CREATE INDEX taxref_tree_path_idx ON taxonomie.taxref_tree USING gist (path); -- TRES important pour les perfs + """) + op.execute(""" + ALTER TABLE taxonomie.bib_attributs ADD recursif BOOLEAN DEFAULT(false); + """) + op.execute(""" + CREATE OR REPLACE VIEW taxonomie.v_recursif_cor_taxon_attribut AS + WITH rec_bib_nom AS ( + SELECT p.cd_ref p_cd_ref, nlevel(p.path), bn.* + FROM taxonomie.taxref_tree child + JOIN taxonomie.bib_noms bn + ON child.cd_ref = bn.cd_ref + JOIN taxonomie.taxref_tree p + ON child.path <@ p.PATH + ) + SELECT * -- Attributs hérités c-a-d avec la propriétée récursif à TRUE + FROM ( + SELECT DISTINCT ON (n.cd_nom, n.cd_ref, cta.id_attribut) n.p_cd_ref, cta.id_attribut , cta.valeur_attribut , n.cd_ref + FROM taxonomie.cor_taxon_attribut cta + JOIN taxonomie.bib_attributs ba + ON ba.id_attribut = cta.id_attribut AND recursif IS TRUE + JOIN rec_bib_nom n + ON n.p_cd_ref = cta.cd_ref + ORDER BY n.cd_nom, cd_ref, cta.id_attribut , nlevel DESC + ) AS h + UNION -- Attributs non hérités + SELECT cta.cd_ref, cta.id_attribut , cta.valeur_attribut , cta.cd_ref + FROM taxonomie.cor_taxon_attribut cta + JOIN taxonomie.bib_attributs ba + ON ba.id_attribut = cta.id_attribut AND recursif IS FALSE; + """) + + +def downgrade(): + op.execute(""" + DROP VIEW taxonomie.v_recursif_cor_taxon_attribut; + """) + op.execute(""" + ALTER TABLE taxonomie.bib_attributs DROP COLUMN recursif; + """) + op.execute(""" + DROP INDEX taxonomie.taxref_tree_cd_nom_idx; + DROP INDEX taxonomie.taxref_tree_path_idx; + DROP MATERIALIZED VIEW taxonomie.taxref_tree; + """) diff --git a/apptax/taxonomie/models.py b/apptax/taxonomie/models.py index 6b984142..0a07a8d7 100644 --- a/apptax/taxonomie/models.py +++ b/apptax/taxonomie/models.py @@ -21,6 +21,7 @@ class BibNoms(serializableModel, db.Model): taxref = db.relationship("Taxref", lazy="select") attributs = db.relationship("CorTaxonAttribut", lazy="select") + h_attributs = db.relationship("VHeritedCorTaxonAttribut", lazy="select") listes = db.relationship("CorNomListe", lazy="select") medias = db.relationship("TMedias", lazy="select") @@ -47,6 +48,33 @@ class CorTaxonAttribut(serializableModel, db.Model): def __repr__(self): return "" % self.valeur_attribut +class VHeritedCorTaxonAttribut(serializableModel, db.Model): + __tablename__ = "v_recursif_cor_taxon_attribut" + __table_args__ = {"schema": "taxonomie"} + id_attribut = db.Column( + db.Integer, + ForeignKey("taxonomie.bib_attributs.id_attribut"), + nullable=False, + primary_key=True, + ) + cd_ref = db.Column( + db.Integer, + ForeignKey("taxonomie.bib_noms.cd_ref"), + nullable=False, + primary_key=True, + ) + p_cd_ref = db.Column( + db.Integer + ) + valeur_attribut = db.Column(db.Text, nullable=False) + bib_nom = db.relationship("BibNoms") + bib_attribut = db.relationship("BibAttributs") + + def __repr__(self): + return "" % self.valeur_attribut + + + class BibAttributs(serializableModel, db.Model): __tablename__ = "bib_attributs" diff --git a/apptax/taxonomie/routesbibattributs.py b/apptax/taxonomie/routesbibattributs.py index 92934c06..adf2f9e8 100644 --- a/apptax/taxonomie/routesbibattributs.py +++ b/apptax/taxonomie/routesbibattributs.py @@ -4,7 +4,7 @@ from sqlalchemy import select, or_ from ..utils.utilssqlalchemy import json_resp -from .models import BibNoms, Taxref, CorTaxonAttribut, BibAttributs +from .models import BibAttributs from . import db adresses = Blueprint('bib_attribut', __name__) diff --git a/apptax/taxonomie/routesbibnoms.py b/apptax/taxonomie/routesbibnoms.py index 8910cf4b..e709a9a8 100644 --- a/apptax/taxonomie/routesbibnoms.py +++ b/apptax/taxonomie/routesbibnoms.py @@ -10,7 +10,7 @@ from .models import ( BibNoms, Taxref, - CorTaxonAttribut, + CorTaxonAttribut, VHeritedCorTaxonAttribut, BibThemes, CorNomListe, BibAttributs, @@ -121,19 +121,19 @@ def getOne_bibtaxonsInfo(cd_nom): cd_ref = db.session.query(Taxref.cd_ref).filter_by(cd_nom=cd_nom).first() obj = {} - # A out des attributs + # Ajout des attributs obj["attributs"] = [] - q = db.session.query(CorTaxonAttribut).filter_by(cd_ref=cd_ref) + q = db.session.query(VHeritedCorTaxonAttribut).filter_by(cd_ref=cd_ref) join_on_bib_attr = False if "id_theme" in request.args.keys() : q = q.join( - BibAttributs, BibAttributs.id_attribut == CorTaxonAttribut.id_attribut + BibAttributs, BibAttributs.id_attribut == VHeritedCorTaxonAttribut.id_attribut ).filter(BibAttributs.id_theme.in_( request.args.getlist("id_theme") )) join_on_bib_attr = True if "id_attribut" in request.args.keys() : if not join_on_bib_attr: q = q.join( - BibAttributs, BibAttributs.id_attribut == CorTaxonAttribut.id_attribut + BibAttributs, BibAttributs.id_attribut == VHeritedCorTaxonAttribut.id_attribut ) q = q.filter(BibAttributs.id_attribut.in_( request.args.getlist("id_attribut") )) bibAttr = q.all() @@ -184,7 +184,7 @@ def getOneFull_bibtaxons(id_nom): # Ajout des attributs obj["attributs"] = [] - for attr in bibTaxon.attributs: + for attr in bibTaxon.h_attributs: o = dict(attr.as_dict().items()) o.update(dict(attr.bib_attribut.as_dict().items())) id = o["id_theme"] diff --git a/static/app/bib_nom/detail/bibNom-detail-tpl.html b/static/app/bib_nom/detail/bibNom-detail-tpl.html index f5e42a79..6aa663c7 100644 --- a/static/app/bib_nom/detail/bibNom-detail-tpl.html +++ b/static/app/bib_nom/detail/bibNom-detail-tpl.html @@ -86,7 +86,7 @@
- +
{{attribut.label_attribut}}{{attribut.label_attribut}}(Hérité) {{attribut.valeur_attribut}}
diff --git a/static/app/bib_nom/edit/bibNom-form-controler.js b/static/app/bib_nom/edit/bibNom-form-controler.js index fc8caa5f..274dd57c 100644 --- a/static/app/bib_nom/edit/bibNom-form-controler.js +++ b/static/app/bib_nom/edit/bibNom-form-controler.js @@ -7,6 +7,7 @@ function($scope, $routeParams, $http, $uibModal, locationHistoryService, $locati self.mediasPath = backendCfg.medias_path; self.bibNom = {}; self.bibNom.attributs_values = {}; + self.bibNom.herited_attributs_values = {}; self.previousLocation = locationHistoryService.get(); self.hideSave = false; self.hideSaveButton = function(){self.hideSave = true;} @@ -38,10 +39,18 @@ function($scope, $routeParams, $http, $uibModal, locationHistoryService, $locati self.bibNom.medias = response.data.medias; } self.bibNom.attributs_values = {}; + self.bibNom.herited_attributs_values = {}; if (response.data.attributs) { angular.forEach(response.data.attributs, function(value, key) { - if (value.type_widget==="number") value.valeur_attribut = Number(value.valeur_attribut); + if (value.type_widget==="number") { + value.valeur_attribut = Number(value.valeur_attribut); + } + if (value.cd_ref !== value.p_cd_ref) { + self.bibNom.herited_attributs_values[value.id_attribut] = value.valeur_attribut; + } + else { self.bibNom.attributs_values[value.id_attribut] = value.valeur_attribut; + } }); delete self.bibNom.attributs; } diff --git a/static/app/bib_nom/edit/bibNom-form-tpl.html b/static/app/bib_nom/edit/bibNom-form-tpl.html index c0a16d39..a3f7ad88 100644 --- a/static/app/bib_nom/edit/bibNom-form-tpl.html +++ b/static/app/bib_nom/edit/bibNom-form-tpl.html @@ -60,6 +60,7 @@
diff --git a/static/app/components/directives/createBibnomsAttributesForm-directives.js b/static/app/components/directives/createBibnomsAttributesForm-directives.js index 4267c592..81623af9 100644 --- a/static/app/components/directives/createBibnomsAttributesForm-directives.js +++ b/static/app/components/directives/createBibnomsAttributesForm-directives.js @@ -5,6 +5,7 @@ app.directive('createBibnomsAttrFormDir', [function () { scope : { attributsDefList:'=', attributsValues:'=', + heritedAttributsValues:'=', userrightlevel:'=' } } diff --git a/static/app/components/directives/createBibnomsAttributesForm-template.html b/static/app/components/directives/createBibnomsAttributesForm-template.html index 777689c5..32b002c6 100644 --- a/static/app/components/directives/createBibnomsAttributesForm-template.html +++ b/static/app/components/directives/createBibnomsAttributesForm-template.html @@ -12,68 +12,76 @@
-
- - - - - - - +
- - - - - + ng-required="{{attrdef.obligatoire}} " + value="{{radval}}"> + {{radval}} + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - TYPE NOT FOUND {{attrdef.type_widget}} + + + + + + + + TYPE NOT FOUND {{attrdef.type_widget}} - + +
+