Précision sur le type de lien d'un document à un autre
Actuellement, la gestion des révisions lors du lien d'un document à un autre est mal définie. Nous voulons pouvoir spécifier quelle révision d'un document lié s'applique : soit la dernière, soit une révision spécifique, soit la dernière révision dans un état spécifique (du cycle de vie).
Nom de l'option : docrev (issue http://dev.freedom-ecm.org/issues/638)
Valeurs de l'option :
Lien unique d'un document à un autre
Il faudrait pouvoir préciser qu'un document lié au document courant ne peut être lié à un autre document. Cela permet d'éviter de lier, par exemple, un compte utilisateur à deux personnes différentes.
Nom de l'option : unique
Valeurs de l'option
Rafraîchissement des champs calculés des documents liés suite à une modification sur un document
Après modification d'un attribut d'un document, l'ancienne valeur de l'attribut peut continuer à apparaître dans les documents liés via la recherche. A l'ouverture du document lié, les attributs calculés sont recalculés de toutes façons et il n'y a pas de problème dans ce cas.
Nous cherchons donc à pouvoir spécifier, dans les options des attributs calculés d'un document, s'il faut recalculer l'attribut après modification du document lié. Il s'agit d'une option pour éviter d'impacter les performances avec des cascades de modifications hors de contrôle.
Nous prendrons l'exemple de l'attribut SERT_SOC d'un document MINUTEMEETING, calculé suivant la fonction ::getDocValue(SERT_PART, US_IDSOCIETY) dans ecm.ods.
Nom de l'option : refreshOn
Valeurs de l'option : Nous voulons pouvoir spécifier s'il faut recalculer suivant différents critères.
| refreshOn | Description |
|---|---|
| SOCIETY.title | Si le document pointé est une société et que son titre a changé alors l'attribut courant prend la nouvelle valeur du titre du document pointé Ceci est aussi applicable aux docid miultiple et aux docid qui sont dans des tableaux |
| .title | Si le document pointé à son titre a changé alors l'attribut courant prend la nouvelle valeur du titre du document pointé |
| SOCIETY.si_phone | Si le document pointé est une société est que son n° de tél a changé alors l'attribut courant prend la nouvelle valeur du n° de tél du document pointé |
| SOCIETY | Si le document pointé est une société et qu'il a été modifié alors la méthode ::refresh() est appelée |
| .* | Si le document pointé a été modifié alors la méthode ::refresh() est appelée |
| .*::my_method() | Si le document pointé a été modifié alors la méthode ::my_method est appelée |
| or(.title,.lock) | Si le titre ou l'état du verrou du document pointé a été modifié alors la méthode ::refresh est appelée |
| or(.title,SOCIETY.si_phone) | Si le titre du document pointé a été modifié ou si c'est une société et que son n° de tél à changé alors la méthode ::refresh est appelée |
| and(.title,SOCIETY.si_phone) | Si le titre du document pointé a été modifié et si c'est une société et que son n° de tél à changé alors la méthode ::refresh est appelée |
| and(.title,SOCIETY.si_phone)::my_method() | Si le titre du document pointé a été modifié et si c'est une société et que son n° de tél à changé alors la méthode ::my_method est appelée |
| and(.title,SOCIETY.si_phone)::my_method(new.si_phone, old.si_phone) | Si le titre du document pointé a été modifié et si c'est une société et que son n° de tél à changé alors la méthode ::my_method est appelée avec la valeur modifié de si_phone et l'ancienne valeur |
Méthode
Lors d'une modification, noter les champs qui ont changé de valeur (potentiellement durant les appels à $doc→setValue()). À la validation des modifications, ($doc→modify()), lancer en tâche de fond la vérification des modifications potentielles à effectuer sur les documents liés.
Si un ou plusieurs documents liés sont modifiés suite à ce traitement, la même méthode cascadera ces nouvelles modifications sur les documents liés au niveau N+2. Il faut garder trace du nombre d'itérations dans la cascade pour éviter une boucle infinie, et toujours privilégier la vérification des modifications potentielles au niveau N+1 à celle du niveau N+2.
Implémentation
A l'import de famille, il faudra renseigner une table spécifique “docrefreshrule” qui liste les refreshOn, contenant les colonnes suivantes :
Lors de la modification d'un document, il faudra insérer dans une table de rafraîchissements à effectuer “docrefreshtask” une ligne contenant
Traitement des rafraîchissements à faire
Nous nous proposons de déférer les traitements à une instance (par contexte) d'un daemon. Ce daemon sera (re)lancé via cron. C'est ce daemon qui se chargera d'insérer les tâches à effectuer dans la table docrefreshtask. Il sera contacté via une socket TCP par Freedom, qui lui enverra un objet Doc sérialisé. le daemon répond un simple ACK à Freedom, insère les valeurs requises dans la table de tâches, puis s'occupe de traiter les informations reçues dans un autre process :
Ce daemon pourrait être, ou non, déporté sur un autre serveur. Avantages d'un déport : pas d'impact sur la charge du serveur Freedom ; plus grande modularité. Inconvénients d'un déport : ce daemon étant chargé de modifier lui-même des documents, il faudra installer certains modules de Freedom sur l'autre serveur afin qu'il puisse bénéficier des APIs Freedom ; léger lag induit par le réseau ; nécessite de faire écouter PostgreSQL sur une interface externe en plus de l'adresse loopback.
D'autre part, ce daemon pourrait, ou non, utiliser sa propre base de données. Avantages d'une base de données propre : pas d'impact sur la base principale freedom lors du traitement/insertion de tâches. Inconvénients : Nécessite que l'insertion des règles (à l'import de familles) soit faite par le daemon aussi ; nécessite deux configurations de base de données, l'une pour les règles et tâches, l'autre pour la modification des documents Freedom ; si le serveur est déporté, installation et maintenance d'une deuxième instance de PostgreSQL.
Dans une optique de simplicité, on fera tourner le daemon sur le même serveur avec la même base de données.
Tests unitaires
Test pas de refresh
Test refreshOn=ANIMAL sur l'attribut CA_IDNOM de la famille CARNETSANTE
Test refreshOn=ANIMAL.AN_ESPECE sur l'attribut CA_IDNOM de la famille CARNETSANTE
Test refreshOn=ANIMAL.AN_SEXE sur l'attribut CA_IDNOM de la famille CARNETSANTE
Test refreshOn=ANIMAL.title sur l'attribut CA_IDNOM de la famille CARNETSANTE
Test refreshOn=or(ANIMAL.AN_ESPECE,ANIMAL.AN_SEXE) sur l'attribut CA_IDNOM de la famille CARNETSANTE
Test refreshOn=or(ANIMAL.AN_PHOTO,ANIMAL.AN_SEXE) sur l'attribut CA_IDNOM de la famille CARNETSANTE
Test refreshOn=and(ANIMAL.AN_ESPECE,ANIMAL.AN_SEXE) sur l'attribut CA_IDNOM de la famille CARNETSANTE
Test refreshOn=and(ANIMAL.AN_ESPECE,ANIMAL.AN_SEXE) sur l'attribut CA_IDNOM de la famille CARNETSANTE
Test refreshOn=::checkAnimalRefresh() sur l'attribut CA_IDNOM de la famille CARNETSANTE
Test refreshOn=::checkAnimalRefresh() sur l'attribut CA_IDNOM de la famille CARNETSANTE