Contrainte de visibilité sur une action

Contrainte de visibilité sur une action
0
Tags: #<Tag:0x00007fec5dc8df38>

Bonjour,

J’ai une action au niveau d’un objet qui fonctionne bien. Quand j’ajoute une contrainte de visibilité sur cette action pour ne l’afficher que lorsqu’un attribut est alimenté, j’arrive à lancer l’action, qui fait bien son travail, mais qui affiche l’erreur suivante à la fin:
debied

Pourtant l’action fonctionne normalement (pas de pb de droit, pas de message d’erreur) sans cette contrainte.

Aurais-je oublié qq choses au niveau de la contrainte ?

Merci d’avance pour votre aide.


Abed

Ca se mord la queue quelque part.

Le code de votre action modifie-t-il la visibilité de l’action ou la valeur du champ contenu dans l’expression ? que retourne-t-elle ?

Oui, le code de l’action remet à vide le champ utilisé dans l’expression.
L’action est affiché si cet attribut est non vide.

Une fois l’action exécutée, je remets à vide l’attribut en question (pour ne plus afficher l’action):

			this.setFieldValue("accountingFiRglPartiel", ''); 									// on remet à vide le montant de règlement partiel.			
			new BusinessObjectTool(this).validateAndSave();		

Comment pourrais-je faire ?
Merci.

Aucune idée à ce stade, je ne comprends pas pourquoi il (re)vérifie les droits au retour de l’action, comme si elle était encore appelée à son propre retour.

Il va falloir qu’on essaye de notre côté car ce n’est pas logique.

J’ai fait le test, je ne reproduis pas ce comportement sur une contrainte back+front sur la visibilité d’une action liée à un champ qui est modifié par elle-même :

  • Le bouton s’active si la contrainte est vérifiée (dans mon cas Action Incrémenter le stock visible que si stock = 0)
  • L’action back fait un update sur le stock du produit (+10)
  • et au retour le bouton a disparu puisque la contrainte est fausse (stock > 0)

Code de la démo :

	public String increaseStock(Map<String, String> params) {
		int q = Tool.parseInt(params.get("demoPrdIncrement"), DEFAULT_INCREMENT);
		if (q > 0) {
			ObjectField s = getField("demoPrdStock");
			s.setValue(s.getInt(0) + q);
			save();
			// Log
			AppLog.info(getClass(), "increaseStock", "Stock for " + getFieldValue("demoPrdReference") + " is now " + s.getValue(), getGrant());
			// User message
			return Message.formatSimpleInfo("DEMO_PRD_STOCK_INCREASED:" + s.getValue());
		} else {
			return Message.formatSimpleError("DEMO_PRD_ERR_INCREMENT:" + q);
		}
	}

Contrainte paramétrée sur l’objet Produit :

Le pb vient de votre code, ou qq chose doit retirer les droits à un autre endroit comme isActionEnable.

Merci @francois pour ce retour.

Je n’arrive toujours pas à trouver la cause de ce message d’erreur. J’ai encore besoin de votre aide svp.

Voici le code (Rhino) de l’action :

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ImmoAccountingFinancial.reglerPartielLigne = function() {
	try {
		if (this.getFieldValue("accountingFiRapproFlag") == '0' ||this.getFieldValue("accountingFiRapproFlag") == '2' ) {// non rapproché ou rapproché partiellement
			console.log("Règlement partiel de la ligne  = " + this.getRowId() + " / Montant = " + this.getFieldValue("accountingFiRglPartiel"));				
			var today = Tool.getCurrentDate();
			var anneeComptable = Tool.getYear(today);
			// On copie la même ligne à l’exception du libellé « REGLEMENT PARTIEL », du montant partiel et de la date comptable (date du jour). 
			var o1 = this.getGrant().getObject("reglerPartielLigne","ImmoAccountingFinancial");		
			o1.setRowId(ObjectField.DEFAULT_ROW_ID);
			o1.resetValues(true);
			o1.setFieldValue("accountingFiMvtType", this.getFieldValue("accountingFiMvtType"));
			o1.setFieldValue("accountingFiYear",anneeComptable);								// On prend l'année de la date du jour
			o1.setFieldValue("accountingFiDateAcc",today);										// On met la date du jour pour la date comptable				
			o1.setFieldValue("accountingFiAmountC", this.getFieldValue("accountingFiRglPartiel"));  	// On prend la valeur du paiement partiel
			o1.setFieldValue("accountingFiDatePrevi", this.getFieldValue("accountingFiDatePrevi"));
			o1.setFieldValue("accountingFiCurrency", this.getFieldValue("accountingFiCurrency"));
			o1.setFieldValue("accountingFiCurrencyAcc", this.getFieldValue("accountingFiCurrencyAcc"));
			o1.setFieldValue("accountingFiImmoPropertyId", this.getFieldValue("accountingFiImmoPropertyId"));
			o1.setFieldValue("accountingFiImmoInvestorId", this.getFieldValue("accountingFiImmoInvestorId"));
			o1.setFieldValue("accountingFiImmoCompanyId", this.getFieldValue("accountingFiImmoCompanyId"));
			o1.setFieldValue("accountingFiLabel","REGLEMENT PARTIEL : " + this.getFieldValue("accountingFiLabel")); // On ajoute " REGLEMENT PARTIEL : "
			o1.setFieldValue("accountingFiAmountD", 0); 	// On met à 0 le D ( c'est un règelemnt partiel et non pas total)
			o1.setFieldValue("accountingFiImmoThirdPartyId", this.getFieldValue("accountingFiImmoThirdPartyId"));
			o1.setFieldValue("accountingFiImmoLeaseId", this.getFieldValue("accountingFiImmoLeaseId"));
			o1.setFieldValue("accountingFiRapproType", this.getFieldValue("accountingFiRapproType")); 
			o1.setFieldValue("accountingFiRapproFlag", '2'); 									// Témoin de rapprochement :  Rapprochement partiel
			o1.setFieldValue("accountingFiImmoBankAccountId", this.getFieldValue("accountingFiImmoBankAccountId"));
			o1.setFieldValue("accountingFiImmoNatPersonId", this.getFieldValue("accountingFiImmoNatPersonId")); 
			o1.setFieldValue("accountingFiImmoLegEntityId", this.getFieldValue("accountingFiImmoLegEntityId"));
			o1.setFieldValue("accountingFiTenantName", this.getFieldValue("accountingFiTenantName")); 
			o1.setFieldValue("accountingFiGeneralAcc", this.getFieldValue("accountingFiGeneralAcc"));
			o1.setFieldValue("accountingFiImmoGenAccountId", this.getFieldValue("accountingFiImmoGenAccountId"));			
			o1.setFieldValue("accountingFiPieceNbr", this.getFieldValue("accountingFiPieceNbr"));						
			o1.setFieldValue("accountingFiRglPartiel", 0);  
			
			new BusinessObjectTool(o1).validateAndSave();
			
			// On met à "Rapproché" la ligne source aussi :
			this.setFieldValue("accountingFiRapproFlag", '2'); 									// Témoin de rapprochement : Rapprochement partiel
			this.setFieldValue("accountingFiRglPartiel", 0); 									// on remet à vide le montant de règlement partiel.			
			new BusinessObjectTool(this).validateAndSave();					
		}
	} catch (e) {
			console.error("ImmoAccountingFinancial.reglerPartielLigne : "+ (e.javaException ? e.javaException.getMessage() : e));				
			return e.javaException ? e.javaException.getMessage() : e;	
	}
	return '';
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Le principe est de dupliquer la ligne en changeant qq attributs, et ensuite, remettre à 0 le champ accountingFiRglPartiel afin de masquer le bouton d’action.

C’est cette valorisation de l’attribut “accountingFiRglPartiel” qui pose pb, car quand je la mets en commentaire, l’action se termine normalement, mais le bouton d’action reste bien sûr affiché.

Voici la contrainte :

Voici l’action :

Je n’ai pas de isActionEnable dans cet objet. Quels seraient les autres endroits où un droit peut être retiré ?
Merci d’avance.

Mon cas semble pareil en terme de design sauf que j’ai testé du java plus robuste en terme de compilation.

Il doit donc y avoir une exception dans votre code ou dans votre exception qui fait que vous tombez dans un “catch final” de Simplicité qui envoie un message d’erreur par défaut ‘access denied’ sur l’action.

Essayez de simplifier votre code comme suit pour tester un retour correct de votre méthode pour exécuter la contrainte :

ImmoAccountingFinancial.reglerPartielLigne = function() {
	try {
		this.setFieldValue("accountingFiRglPartiel", 0);
		this.save();
	} catch (e) {
		console.log("Erreur reglerPartielLigne");
		return "Erreur !";
	}
	console.log("Succès reglerPartielLigne");
	return null; // ou "OK#INFO"
};

puis réactiver votre code par block jusqu’à trouver le bug.

Une autre piste vient du fait que le retour String d’une action codée en Rhino se concatène avec la méthode Java si elle est implémenté par ailleurs (Simplicité essaye de faire un invoke method sur l’objet java, car la méthode peut exister dans le socle ou dans un objet parent par héritage…).

Ca expliquerait que le contrôle d’accès à cette action se fasse 2 fois comme vous le décrivez, et qu’à la seconde, l’action ne soit plus autorisée par contrainte.

Je vais essayer cette piste, et si c’est ça il faudra revoir le contrôle d’accès dans le cas de Rhino…

Suite du test refait en Rhino : ça fonctionne normalement. L’action est toujours habilitée et s’affiche conformément à la contrainte.

Le message “Access denied…” signifie que l’action ne fait plus partie des droits dans la session de l’utilisateur au moment où elle est rappelée.

Pour info, la contrainte change uniquement le flag “enabled” de l’action en session mais ne la retire pas des droits de l’utilisateur : c’est comme faire un action.setEnabled(true|false) dans le initUpdate.

Il faut donc chercher la solution dans votre code, partout où vous accédez aux droits de l’utilisateur ou via hooks.

Les actions sont accessibles par là :

getGrant().getObjectActions()
getGrant().getActions()
obj.getActions()

Et surtout au niveau de vos 2 objets manipulés par l’action (validate, create, update, save, isUpdateEnable…).

Si vous n’y arrivez pas, retirez la contrainte, et utilisez le hook isActionEnable.

Bonjour @francois,
en réactivant mon code par bloc, j’ai trouvé l’endroit qui qui pose pb (bug ?), il s’agit de la valorisation du champ accountingFiRglPartiel à 0, non pas pour celui de la ligne en cours (this.) mais pour la nouvelle ligne générée (o1.).
En utilisant this.getActions() avant la génération de la ligne j’obtiens :

{"confirm":true,"name":"ImmoAccountingFinancial_ReglerPartiel-A","id":"1308","type":79,"enabled":true}]

Et après la génération :

{"confirm":true,"name":"ImmoAccountingFinancial_ReglerPartiel-A","id":"1308","type":79,"enabled":false}]

J’ai donc ajouté un action.setEnabled(true) entre la génération de la nouvelle ligne et la mise à jour de la ligne en cours et je n’ai plus d’erreur.

Encore merci pour votre aide précieuse.

Effectivement votre premier objet créé doit agir sur l’action puisque c’est le même objet et que votre contrainte est typée “back”, lorsque o1 est créé la contrainte est lancée.

C’est là que ça se mordait la queue, on ne peut rien faire dans le socle.

Il fallait bien remettre l’action en “enabled” par code
ou ajouter une règle dans la contrainte pour ne l’appliquer que si l’instance n’était pas “reglerPartielLigne” (votre code pour créer une ligne sur le même objet) à la place de “true”.