Select sur Objet service (suite)

Request description

Bonjour,

Après avoir migré en 6.2, je rencontre toujours des soucis avec l’utilisation d’une action en ligne sur objet Service. Cela fait suite à ce ticket.

Mon problème est qu’à l’appel de l’action, les valeurs de mon instance d’objet sont ceux de la dernière ligne de la liste, et non celle sur laquelle j’ai cliqué.

Exemple :
Je clique sur l’action pour l’IRN-79643, mais les valeurs utilisées sont celles de l’IRN-79648.

J’ai essayé de surcharger le selectService pour valoriser correctement la ligne, mais cela génère une erreur : il semble que dans la variable passée rowId, j’ai le nom de l’action au lieu du rowId.

	@Override
	public boolean selectService(String rowId, boolean copy) {
		AppLog.info("selectService " + rowId + " IRN " + getFieldValue("rciSnaIrn"), getGrant());
		setValues(getCurrentList().get(Integer.parseInt(rowId)));
		return true;
	}

Les logs :

2025-06-04 08:34:42,754|SIMPLICITE|INFO||http://simplicite-dev-5fc8c64d94-t584s:8080||INFO|testRespApp|com.simplicite.objects.RCIB.RciSnowApplication|selectService||Event: selectService createApp IRN IRN-79648
2025-06-04 08:34:42,754|SIMPLICITE|ERROR||http://simplicite-dev-5fc8c64d94-t584s:8080||ECORED0001|system|com.simplicite.util.engine.ObjectDirect|select||Error RciSnowApplication
java.lang.NumberFormatException: For input string: "createApp"

Ma question est la suivante : comment récupérer les valeurs de la bonne ligne dans mon action, sans devoir réappeler mon API inutilement ?

Mon code ci-dessous

	@Override
	public boolean selectService(String rowId, boolean copy) {
		AppLog.info("selectService " + rowId + " IRN " + getFieldValue("rciSnaIrn"), getGrant());
		setValues(getCurrentList().get(Integer.parseInt(rowId)));
		return true;
	}
	
	@Override
	public long countService() {
		
		String apiFilters = formatFilters();
		long snowCount = RciSnow.countSnowAppWithLimit(null, apiFilters, getGrant());
		getGrant().setParameter("RCI_SNOW_COUNT",snowCount);
		return snowCount;
	}

	@Override
	public List<String[]> searchService(boolean pagine) {

		AppLog.info("Entering searchService pagine " + pagine + "getSearchLimit() " + Integer.toString(getMaxRows()) + " getCurrentPage() " + Integer.toString(getCurrentPage()), getGrant());

		List<String[]> snowApps = new ArrayList<>();

		try
		{
			String apiFilters = formatFilters(), appExistsFilter = "";
			
			String limit = "", page = "";
			
			if (getField("rciSnaAppExists").isFiltered())
				appExistsFilter = getFieldFilter("rciSnaAppExists");
			
			if (appExistsFilter.isEmpty())
			{
				limit = Integer.toString(getMaxRows());
				page = Integer.toString(getCurrentPage());
				//setLimit(true);
			}
			else
			{
				limit = getGrant().getParameter("RCI_SNOW_COUNT");
				page = "0";
				//setLimit(false);
			}
			
			String res = RciSnow.reqSnowAppWithLimit(null, limit, page, apiFilters, getGrant());
			
			if (res != null)
			{
				JSONObject resJSON = new JSONObject(res);
				
				if (resJSON != null && resJSON.getJSONArray("result") != null && resJSON.getJSONArray("result").length() > 0)
				{

					JSONArray appsJSON = resJSON.getJSONArray("result");
					AppLog.info(getClass(), "appsJSON : ", appsJSON.length() + " " + appsJSON.toString(), getGrant());
					
					String key = "";
				    String snaField = "";
				    String snowField = "";
					
					for (int j = 0 ; j < appsJSON.length() ; j++)
					{
						JSONObject appJSON = appsJSON.getJSONObject(j);
						AppLog.info(getClass(), "appJSON : ", Integer.toString(j) + " " +  appJSON.toString(), getGrant());
						AppLog.info(getClass(), "IRN : ", appJSON.getString("name") + "size " + getFields().size(), getGrant());

						String[] snowApp = new String[getFields().size()];
						
						String irn = appJSON.getString("name");
						snowApp[getFieldIndex("rciSnaIrn")] = irn;
						
						Boolean appExists = appExists(irn);
						snowApp[getFieldIndex("rciSnaAppExists")] = Boolean.toString(appExists);
						snowApp[0] = Integer.toString(j + 1);
						AppLog.info(getClass(), "snowApp rowid 1 : ", snowApp[0], getGrant());
						if (appExistsFilter.isEmpty() || ((appExistsFilter.equals("1") && appExists) || (appExistsFilter.equals("0") && !appExists)))
						{
							for (Map.Entry<String, String> entry : RciSnow.CMDB_EAR_FIELDS.entrySet()) {
											
							    key = entry.getKey();
							    snaField = "rciSna" + key;
							    snowField = entry.getValue();
							    
							    if (getField(snaField, false) != null)
							    	snowApp[getFieldIndex(snaField)] = RciSnow.cmdbToEar(snowField, appJSON);
							}
													AppLog.info(getClass(), "snowApp rowid 2 : ", snowApp[0], getGrant());

							snowApps.add(snowApp);
							AppLog.info(getClass(), "snowApps : ", snowApps.get(0)[0], getGrant());
						}

					}
				}
			}
			
			
		}
		catch (Exception e) {
			AppLog.error(e, getGrant());
		}

		return snowApps;
	}

Et la version

[Platform]
Status=OK
Version=6.2.10
BuiltOn=2025-05-23 10:17
Git=6.2/db71f45b7b47f1aea2d669dc5b22c5369ec75d92

Merci d’avance pour votre aide !
Emmanuelle

Bonjour,

Il faut surement ajouter un setCurrentList(snowApps); à la fin du searchService.
car le selectService utilise déjà les records courants par défaut, pas la peine de le refaire.
et il doit aussi gérer le cas d’une création ou recopie.

Voilà la code par défaut

	public boolean selectService(String rowId, boolean copy)
	{
		// Default implementation is looking for the matching record for specified row ID
		// in the current list (supposed to be set by the searchService)

		List<String[]> rows = getCurrentList();
		if (rowId==null || Tool.isEmpty(rows))
			return false;

		for (String[] row : rows)
		{
			if (row!=null && row.length>0 && rowId.equals(row[0]))
			{
				setValues(row);
				if (copy)
					setRowId(ObjectField.DEFAULT_ROW_ID);
				return true;
			}
		}
		return false;
	}

Par contre ce n’est pas normal d’avoir un nom d’action à la place du rowId sur une action de liste. On va vérifier.

1 Like

D’accord donc normalement, sans surcharger le selectService (sans get ni set currentList), je devrais bien avoir mes valeurs, ce qui n’est pas le cas.
J’attends votre retour, merci !

Le rowId passé en paramètre est bien le premier champ du tableau / de l’objet.
Le premier champ n’est peut être pas un rowId mais un libellé.

Bref il faut être sur du contenu de snowApp[0] et de lister les getFields() de votre objet pour voir si le 1er est un rowId. Sinon il faut surcharger dans la définition le custom rowId de l’objet avec ce champ pour que Simplicité n’ajoute pas un “row_id” en premier champ.

En fait, j’ai bien le rowId au premier appel du selectService, et il prend le nom de l’action par la suite.
Et l’IRN est correct dans le initAction mais pas dans le selectService.
Je suis perdue !

2025-06-04 09:47:20,884|SIMPLICITE|INFO||http://simplicite-dev-5fc8c64d94-t584s:8080||INFO|testRespApp|com.simplicite.objects.RCIB.RciSnowApplication|selectService||Event: selectService 1 IRN IRN-79648
2025-06-04 09:47:20,893|SIMPLICITE|INFO||http://simplicite-dev-5fc8c64d94-t584s:8080||INFO|testRespApp|com.simplicite.objects.RCIB.RciSnowApplication|initAction||Event: initAction
2025-06-04 09:47:20,894|SIMPLICITE|INFO||http://simplicite-dev-5fc8c64d94-t584s:8080||INFO|testRespApp|com.simplicite.objects.RCIB.RciSnowApplication|initAction||Event: IRN IRN-79643
2025-06-04 09:47:25,211|SIMPLICITE|INFO||http://simplicite-dev-5fc8c64d94-t584s:8080||INFO|testRespApp|com.simplicite.objects.RCIB.RciSnowApplication|selectService||Event: selectService createApp IRN IRN-79648

[EDIT] Dans les deux cas mon premier champ est le row_id

2025-06-04 10:25:05,660|SIMPLICITE|INFO||http://simplicite-dev-5fc8c64d94-t584s:8080||INFO|testRespApp|com.simplicite.objects.RCIB.RciSnowApplication|selectService||Event: selectService getFields().get(0).getName() row_id
2025-06-04 10:25:05,668|SIMPLICITE|INFO||http://simplicite-dev-5fc8c64d94-t584s:8080||INFO|testRespApp|com.simplicite.objects.RCIB.RciSnowApplication|createApp||Event: createApp getFields().get(0).getName() row_id
  • il faut faire un setCurrentList dans le searchServicepour garder la page en mémoire et s’en servir dans le selectService par défaut
  • debugger l’intégralité du contenu des tableaux issus du search ?
  • est-ce conforme à la définition de l’objet : custom rowID ? attributs ?
  • c’est quoi createApp au juste ? une donnée, un nom d’action (du coup mal nommée) ?..

Alors, mon code n’était pas bon sur la génération des row_id. Après correction + ajout du get et set currentList j’ai enfin les bonnes valeurs.
Par contre j’ai toujours le nom de l’action (peut-être mal nommée, mais je n’ai pas de proposition de renomage au save) passée en paramètre au premier appel du selectService, ce qui génère une erreur. Mais ce n’est plus bloquant pour nous.

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.