Subversion Repositories eFlore/Applications.del

Compare Revisions

Ignore whitespace Rev 1443 → Rev 1444

/trunk/services/modules/0.1/determinations/ValiderDetermination.php
36,13 → 36,10
$this->verifierParametres($ressources, $parametres);
$id_proposition = $ressources[1];
$retour = $this->modifierObservationParDetermination($id_proposition, $parametres);
if ($retour == false) {
if(!$this->modifierObservationParDetermination($id_proposition, $parametres))
throw new Exception($e, RestServeur::HTTP_CODE_ERREUR);
} else {
RestServeur::envoyerEnteteStatutHttp(RestServeur::HTTP_CODE_OK);
}
 
RestServeur::envoyerEnteteStatutHttp(RestServeur::HTTP_CODE_OK);
}
public function verifierParametres($ressources, $parametres) {
66,6 → 63,10
private function modifierObservationParDetermination($id_proposition, $parametres) {
$informations_proposition = self::obtenirInformationDetermination($this->bdd, $id_proposition, $parametres['auteur.id']);
if(! $informations_proposition) {
throw new Exception("Cette proposition est invalide.", RestServeur::HTTP_CODE_ERREUR);
}
 
$id_observation = $informations_proposition['ce_observation'];
// obtenirInformationsObservation()
$informations_observation = $this->bdd->recuperer(sprintf('SELECT * FROM del_observation WHERE id_observation = %d',
74,11 → 75,21
if(! $est_autorise) {
throw new Exception("Seul l'utilisateur ayant saisi l'observation peut la valider : veuillez vous identifier.\n",
RestServeur::HTTP_CODE_ERREUR);
return;
}
 
$informations_proposition['ce_utilisateur'] = $informations_observation['ce_utilisateur'];
return $this->envoyerRequeteModificationObservation($id_observation, $informations_proposition);
 
$ret = $this->envoyerRequeteModificationObservation($id_observation, $informations_proposition);
// cf cel/jrest/services/CelValidationObservation.php::updateElement()
// TODO: check sur HTTP code == 200, plutôt que sur texte
if($ret == 'ok' || $ret == 'OK') {
// remet à 0 le status "proposition_retenue" pour toutes les propositions faites sur cette
// observation à l'exception de celle désormais validée
$this->bdd->requeter(sprintf('UPDATE del_commentaire SET proposition_retenue = IF(id_commentaire = %d, 1, 0)' .
' WHERE ce_observation = %d -- %s',
$informations_proposition['id_commentaire'], $id_observation, __FILE__ . ':' . __LINE__));
}
return $ret;
}
private function comparerAuteurObservationUtilisateurIdentifie($ce_utilisateur) {
/trunk/services/modules/0.1/observations/ListeObservations2.php
481,6 → 481,10
'(vdi.mots_cles_texte IS NULL OR vdi.mots_cles_texte NOT LIKE "%aDeterminer%"',
)) . ')';
}
if(array_key_exists('validees', $val)) {
//On récupère toutes les observations ayant un commentaire doté de proposition_retenue = 1
$req['join'][] = 'INNER JOIN del_commentaire AS dc ON vdi.id_observation = dc.ce_observation AND dc.proposition_retenue = 1';
}
 
// solution n°1: impraticable
if(false && array_key_exists('endiscussion', $val)) {
704,10 → 708,10
$p['masque.tag'] = implode('|', array_filter($x));
}
 
// masque.type: ['adeterminer', 'aconfirmer', 'endiscussion']
// masque.type: ['adeterminer', 'aconfirmer', 'endiscussion', 'validees']
if(isset($params['masque.type'])) {
$p['masque.type'] = array_flip(array_intersect(array_filter(explode(';', $params['masque.type'])),
array('adeterminer', 'aconfirmer', 'endiscussion')));
array('adeterminer', 'aconfirmer', 'endiscussion', 'validees')));
}
 
 
/trunk/doc/bdd/sql/del.sql
100,7 → 100,7
`intitule` VARCHAR(255) NOT NULL ,
`descriptif` TEXT NULL ,
`tag` VARCHAR(255) NULL ,
`mots_cles` TEXT NULL COMMENT 'Mots clés associés au protocole, ceux ci déterminent les mots clés présentés \"à cocher\" dans l\'interface, lorsque le protocole est selectionné' ,
`mots_cles` VARCHAR(600) NOT NULL COMMENT 'Mots clés associés au protocole, ceux ci déterminent les mots clés présentés \"à cocher\" dans l\'interface, lorsque le protocole est selectionné' ,
PRIMARY KEY (`id_protocole`) )
ENGINE = MyISAM
DEFAULT CHARACTER SET = utf8
156,8 → 156,8
CREATE TABLE IF NOT EXISTS `del_commentaire` (
`id_commentaire` BIGINT NOT NULL AUTO_INCREMENT ,
`ce_observation` BIGINT NOT NULL ,
`ce_proposition` INT NULL DEFAULT '0' ,
`ce_commentaire_parent` BIGINT NULL DEFAULT '0' ,
`ce_proposition` INT NULL DEFAULT 0 ,
`ce_commentaire_parent` BIGINT NULL DEFAULT 0 ,
`texte` TEXT NULL DEFAULT NULL ,
`ce_utilisateur` INT NULL DEFAULT '0' ,
`utilisateur_prenom` VARCHAR(255) NOT NULL ,
171,7 → 171,8
`famille` VARCHAR(255) NULL DEFAULT NULL ,
`nom_referentiel` VARCHAR(255) NULL DEFAULT NULL ,
`date` DATETIME NOT NULL COMMENT 'Date de création du commentaire.' ,
`proposition_initiale` INT(1) NOT NULL DEFAULT '0' ,
`proposition_initiale` INT(1) NOT NULL DEFAULT 0 COMMENT 'La proposition initiale est le nom_sel d\'origine copié ici dès lors que des commentaires adviennent.' ,
`proposition_retenue` INT(1) NOT NULL DEFAULT 0 COMMENT 'La proposition \"validée\" une fois que l\'auteur à validé et que le nom_sel de cel_obs a été modifié à partir du nom_sel de del_commentaire.' ,
PRIMARY KEY (`id_commentaire`) )
ENGINE = MyISAM
DEFAULT CHARACTER SET = utf8
/trunk/doc/bdd/schema_bdd_del.mwb
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/doc/bdd/schema_bdd_del.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/scripts/modules/maj/201310-propret.sql
New file
0,0 → 1,103
DELIMITER |
 
-- initialisation (structure)
DROP PROCEDURE IF EXISTS update_struct;
CREATE PROCEDURE update_struct()
BEGIN
-- ajout de la colonne "proposition_retenue"
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S21' SELECT "colonne proposition_retenue déjà existante"; /* = Duplicate column name */
ALTER TABLE `BASEDEL`.`del_commentaire` ADD `proposition_retenue` INT(1) NOT NULL DEFAULT 0 COMMENT "La proposition \"validée\" une fois que l'auteur à validé et que le nom_sel de cel_obs a été modifié à partir du nom_sel de del_commentaire."; -- '
END;
|
 
-- petite functon bonus
DROP PROCEDURE IF EXISTS getCommentaires;
CREATE PROCEDURE getCommentaires(IN _s1 INT(20))
BEGIN
SELECT id_commentaire, ce_observation, ce_proposition, texte, nom_sel, nom_sel_nn, proposition_retenue FROM `BASEDEL`.`del_commentaire` WHERE ce_observation = _s1;
END;
|
 
-- procédure créant des tables temporaires permettant de faciliter le processus de MAJ
DROP PROCEDURE rebuild_retenues;
CREATE PROCEDURE rebuild_retenues()
BEGIN
DROP TEMPORARY TABLE IF EXISTS _temp_having_retenue, _temp_multi_prop, _temp_mono_prop;
 
-- les observations déjà retenues (pour pouvoir être exclues des processus postérieurs)
CREATE TEMPORARY TABLE _temp_having_retenue ENGINE=MEMORY AS ( \
SELECT ce_observation FROM `BASEDEL`.`del_commentaire` co WHERE proposition_retenue = 1);
 
-- observations ayant plusieurs propositions (= commentaire dont nom_sel IS NOT NULL)
CREATE TEMPORARY TABLE IF NOT EXISTS _temp_multi_prop ENGINE=MEMORY AS ( \
SELECT ce_observation FROM `BASEDEL`.`del_commentaire` co \
WHERE nom_sel IS NOT NULL \
AND proposition_retenue = 0 /* == ce_observation NOT IN (SELECT ce_proposition FROM _temp_having_retenue) */ \
GROUP BY ce_observation HAVING COUNT(id_commentaire) > 1); -- 1053
 
-- observations ayant une seule proposition (= commentaire dont nom_sel IS NOT NULL)
CREATE TEMPORARY TABLE IF NOT EXISTS _temp_mono_prop ENGINE=MEMORY AS ( \
SELECT ce_observation FROM `BASEDEL`.`del_commentaire` \
WHERE nom_sel IS NOT NULL \
AND proposition_retenue = 0 /* == ce_observation NOT IN (SELECT ce_proposition FROM _temp_having_retenue) */ \
GROUP BY ce_observation HAVING COUNT(id_commentaire) = 1);
 
END;
|
 
DELIMITER ;
 
 
CALL update_struct();
-- table temporaire de tous les comptages (somme des votes pour chaque proposition de del_commentaire):
CREATE TEMPORARY TABLE IF NOT EXISTS _temp_stats ENGINE=MEMORY AS ( SELECT ce_proposition, SUM(valeur) AS val FROM `BASEDEL`.`del_commentaire_vote` GROUP BY ce_proposition); -- 5912
-- propositions ayant eu au moins 1 vote positif non-anonyme
CREATE TEMPORARY TABLE IF NOT EXISTS _temp_authvotepos ENGINE=MEMORY AS (SELECT DISTINCT ce_proposition FROM `BASEDEL`.`del_commentaire_vote` WHERE valeur = 1 AND LENGTH(ce_utilisateur) != 32 ORDER BY ce_proposition); -- 3794
CALL rebuild_retenues(); -- initialisation
 
-- core
-- SELECT ce_observation, id_commentaire FROM `BASEDEL`.`del_commentaire` co INNER JOIN _temp_multi_prop mp USING (ce_observation) INNER JOIN `BASECEL`.`cel_obs` ce ON mp.ce_observation = id_observation AND (co.nom_sel = ce.nom_sel AND co.nom_sel_nn = ce.nom_sel_nn) WHERE co.nom_sel_nn != 0 AND co.proposition_retenue = 0; -- 470, dont 464 ce_observation unique
-- SELECT ce_observation, id_commentaire FROM `BASEDEL`.`del_commentaire` co INNER JOIN _temp_multi_prop mp USING (ce_observation) INNER JOIN `BASECEL`.`cel_obs` ce ON mp.ce_observation = id_observation AND (co.nom_sel = ce.nom_sel OR co.nom_sel_nn = ce.nom_sel_nn) WHERE co.nom_sel_nn != 0 AND co.proposition_retenue = 0; -- 520, dont 493 ce_observation unique
 
-- Étant donné les doublons nous pouvons commencer ou finir par filtrer sur les stats de vote
-- Comme il est plus simple de finir par ça, commençons correctement par les nom_sel comme ci-dessus avec ceux sans ambiguité:
-- C'est à dire observations dotées de multiples proposition dont une et une seule match exactement le nom-sel du carnet en ligne
CREATE TEMPORARY TABLE IF NOT EXISTS _temp_updatable1 ENGINE=MEMORY AS ( \
SELECT /* ce_observation, */ id_commentaire FROM `BASEDEL`.`del_commentaire` co \
INNER JOIN _temp_multi_prop mp USING (ce_observation) /* faisant partie des observations ayant plusieurs propositions */ \
INNER JOIN `BASECEL`.`cel_obs` ce ON mp.ce_observation = id_observation AND (co.nom_sel = ce.nom_sel AND co.nom_sel_nn = ce.nom_sel_nn) \
WHERE co.nom_sel_nn != 0 \
GROUP BY co.ce_observation HAVING COUNT(co.id_commentaire) = 1 /* observations n'ayant pas d'ambiguité sur le commentaire correspondant au nom du carnet en ligne */ ); -- 335
 
UPDATE `BASEDEL`.`del_commentaire` co SET co.proposition_retenue = 1 WHERE co.id_commentaire IN (SELECT id_commentaire FROM _temp_updatable1);
SELECT ROW_COUNT() AS "nb MAJ par match sur nom_sel sans ambiguité";
CALL rebuild_retenues();
 
 
-- Pour les observations ayant plusieurs nom-sel communs au carnet en ligne, il s'agit de ne sélectionner que celle
-- ayant le plus de vote (idéalement les propositions doublonnes ne devraient pas exister)
CREATE TEMPORARY TABLE IF NOT EXISTS _temp_updatable2 ENGINE=MEMORY AS ( \
SELECT co.ce_observation, id_commentaire, i1.val FROM `BASEDEL`.`del_commentaire` co \
INNER JOIN _temp_multi_prop mp USING (ce_observation) /* uniquement les multi-propositions, inclue le check sur _temp_having_retenue */ \
INNER JOIN (SELECT ce_proposition, val FROM _temp_stats) AS i1 ON i1.ce_proposition = co.id_commentaire /* et ayant des votes */ \
INNER JOIN `BASECEL`.`cel_obs` ce ON co.ce_observation = ce.id_observation AND (co.nom_sel = ce.nom_sel AND co.nom_sel_nn = ce.nom_sel_nn) /* et un nom_sel acceptable */ \
WHERE co.nom_sel_nn != 0 \
GROUP BY ce_observation HAVING i1.val = MAX(i1.val) /* parmis les doublonnes, prendre la proposition ayant le plus de SUM(votes) */ \
ORDER BY ce_observation ); -- 249 (sans le processus précédent, moins autrement s'il l'on exclue les observation déjà "validée")
 
UPDATE `BASEDEL`.`del_commentaire` co SET co.proposition_retenue = 1 WHERE co.id_commentaire IN (SELECT id_commentaire FROM _temp_updatable2);
SELECT ROW_COUNT() AS "nb MAJ par nombre de vote";
CALL rebuild_retenues();
 
-- Enfin, les observation n'ayant qu'une seule proposition sont passées comme retenues si
-- elles ont été notée positivement au moins une fois par un utilisateur authentifié
CREATE TEMPORARY TABLE IF NOT EXISTS _temp_updatable3 ENGINE=MEMORY AS ( \
SELECT co.id_commentaire FROM `BASEDEL`.`del_commentaire` co \
INNER JOIN _temp_mono_prop AS i1 USING (ce_observation) /* l'inverse de _temp_multi_prop, inclue le check sur _temp_having_retenue */ \
INNER JOIN _temp_authvotepos ta ON co.id_commentaire = ta.ce_proposition /* et uniquement si faisant partie des commentaires doté d'un vote positif non-anonyme */ \
INNER JOIN `BASECEL`.`cel_obs` ce ON co.ce_observation = ce.id_observation AND (co.nom_sel = ce.nom_sel AND co.nom_sel_nn = ce.nom_sel_nn) \
WHERE co.nom_sel_nn != 0); -- 2216 sans test sur cel_obs, 2193 avec
 
UPDATE `BASEDEL`.`del_commentaire` co SET co.proposition_retenue = 1 WHERE co.id_commentaire IN (SELECT id_commentaire FROM _temp_updatable3);
SELECT ROW_COUNT() AS "nb MAJ ayant 1 seule proposition mais un vote non-anonyme positif";
CALL rebuild_retenues();
/trunk/scripts/modules/maj/Makefile
19,7 → 19,18
o_maj1: clean o_201309-index-views
cat $(fichiers_generes) > maj1.comp.sql
 
 
# maj1 contient: 201310-propret.sql
o_maj2: fichiers_generes = $(addsuffix .comp.sql,$(filter-out clean,$?))
o_maj2: clean o_201310-propret
cat $(fichiers_generes) > maj2.comp.sql
 
 
# SHOW INDEX FROM cel_obs WHERE Key_name = 'transmission';
# SHOW INDEX FROM cel_obs WHERE Key_name = 'date_transmission';
o_201309-index-views:
$(call do_subst,201309-index-views.sql) > $@.comp.sql
 
# SHOW COLUMNS FROM del_commentaire LIKE 'proposition_retenu';
o_201310-propret:
$(call do_subst,201310-propret.sql) > $@.comp.sql
/trunk/src/org/tela_botanica/del/client/vues/identiplante/moteur/MoteurIdentiplanteVue.java
30,7 → 30,7
Panel zoneRecherche, zoneResultats;
 
@UiField
Label ongletTout, ongletADeterminer, ongletEnDiscussion;
Label ongletTout, ongletADeterminer, ongletEnDiscussion, ongletValidees;
 
public HasWidgets getZoneRecherche() {
return zoneRecherche;
62,6 → 62,11
}
 
@Override
public HasClickHandlers getOngletValidees() {
return ongletValidees;
}
 
@Override
public void setOngletADeterminerActif() {
nettoyerOngletsActifs();
ongletADeterminer.addStyleName("onglet-actif");
78,11 → 83,18
nettoyerOngletsActifs();
ongletEnDiscussion.addStyleName("onglet-actif");
}
 
@Override
public void setOngletValideesActif() {
nettoyerOngletsActifs();
ongletValidees.addStyleName("onglet-actif");
}
public void nettoyerOngletsActifs() {
ongletTout.removeStyleName("onglet-actif");
ongletADeterminer.removeStyleName("onglet-actif");
ongletEnDiscussion.removeStyleName("onglet-actif");
ongletValidees.removeStyleName("onglet-actif");
}
public void mettreAJourOngletEnFonctionDuCache() {
93,6 → 105,8
setOngletADeterminerActif();
} else if (statut.equals("endiscussion")) {
setOngletEnDiscussionActif();
} else if (statut.equals("validees")) {
setOngletValideesActif();
}
}
 
/trunk/src/org/tela_botanica/del/client/vues/identiplante/moteur/MoteurIdentiplanteVue.ui.xml
17,6 → 17,7
<g:HTMLPanel styleName="zone-onglets">
<g:Label styleName="onglet onglet-actif" text="Tout" ui:field="ongletTout"></g:Label>
<g:Label styleName="onglet" text="A déterminer" ui:field="ongletADeterminer"></g:Label>
<g:Label styleName="onglet" text="Validées" ui:field="ongletValidees"></g:Label>
<g:Label styleName="onglet" text="En discussion" ui:field="ongletEnDiscussion"></g:Label>
</g:HTMLPanel>
<g:HTMLPanel>
/trunk/src/org/tela_botanica/del/client/vues/identiplante/moteur/MoteurIdentiplantePresenteur.java
33,6 → 33,8
public HasClickHandlers getOngletADeterminer();
public HasClickHandlers getOngletTout();
 
public HasClickHandlers getOngletValidees();
public void setOngletADeterminerActif();
39,6 → 41,8
public void setOngletToutActif();
public void setOngletEnDiscussionActif();
 
public void setOngletValideesActif();
}
 
107,6 → 111,17
vue.setOngletEnDiscussionActif();
}
});
 
vue.getOngletValidees().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
CacheClient.getInstance().setFiltreStatut("validees");
CacheClient.getInstance().setPageCouranteRechercheObservations(1);
chercherObservations();
vue.setOngletValideesActif();
}
});
}
 
}