Meilleure façon d'implémenter un Business Process avec des champs d'objet métier spécifiques à chaque étape

Request description

Bonjour,

Je travaille actuellement sur la mise en place d’un Business Process dans Simplicité, et j’ai rencontré un défi que je souhaiterais résoudre de la manière la plus efficace possible.

Mon Business Process implique un objet métier complexe avec de nombreux champs. Cependant, à chaque étape du processus, je n’ai besoin que de certains champs spécifiques de cet objet métier pour être visibles et éditables.

J’ai exploré diverses options pour gérer cela mais je ne suis pas sûr de la meilleure approche à suivre pour optimiser la gestion des champs à chaque étape.

Je me demande s’il existe une manière recommandée ou une meilleure pratique pour diviser les champs de l’objet métier en différentes étapes de mon Business Process, en garantissant que seuls les champs pertinents sont visibles et éditables à chaque étape.

Toute orientation ou conseil que vous pourriez fournir serait grandement apprécié. Je suis ouvert à toute suggestion ou méthode que vous pourriez recommander pour résoudre ce problème.

Merci d’avance pour votre aide et vos conseils précieux.

Cordialement,
Elyass

Technical information

Instance /health

[Platform]
Status=OK
Version=5.3.12
BuiltOn=2023-08-25 09:44
Git=5.3/e2cd9f0ea850e3845169840790a1a6ef043fed16
Encoding=UTF-8
EndpointIP=149.202.171.75
EndpointURL=http://renault.simplicite.io:10488
TimeZone=Europe/Paris
SystemDate=2023-09-01 10:40:25

Bonjour,

Le plus simple si votre processus est supporté par un seul objet métier et un diagramme d’états, est de rendre conditionnel les attributs et/ou les zones d’attributs

  • par contraintes de visibilité s’il y a peu de règles, sinon ça devient lourd à paramétrer/maintenir
  • ou sinon par code dans les hook initCreate/initCopy et initUpdate en fonction de l’état de l’objet

Exemple :

private void prepareFields() {
  // Etat courant de l'ENUM qui supporte le diagramme d'états
  String s = getStatus();
  // masquer un champ à l'étape 1
  getField("field1").setVisibility(s.equals("STEP1") ? ObjectField.VIS_NOT : ObjectField.VIS_FORM);
  // masquer une zone à l'étape 2
  getFieldArea("myobject-area1").setVisible(!s.equals("STEP2"));
}
@Override
public void initCreate() {
  super.initCreate();
  setStatus("INIT"); // état initial de l'ENUM
  prepareFields();
}
@Override
public void initCopy() {
  super.initCopy();
  initCreate(); // comme la création
}
@Override
public void initUpdate() {
  super.initUpdate();
  prepareFields();
}

Bonjour François,

Je vous remercie de votre réponse.

Cependant, je souhaiterais clarifier un point. Mon objectif n’est pas de gérer la visibilité des champs en fonction de l’état de l’objet, mais plutôt en fonction de l’étape spécifique de mon processus métier. J’ai bien vu que vous avez mentionné l’utilisation de l’ENUM pour gérer les états de l’objet, mais dans ce cas précis, je cherche à ce que certains champs de mon objet métier ne soient visibles que dans certaines étapes du processus, indépendamment de l’état global de l’objet.

Pour illustrer (cf. capture ci-dessous), dans ma première étape “CPSC-GI” (en rouge) de mon processus, je souhaiterais afficher certains champs, puis masquer ces champs lors de la transition vers l’étape suivante, “CPSC-DPD” (en vert).

Est-il possible de mettre en place cette gestion de la visibilité des champs en fonction de l’étape du processus plutôt qu’en fonction de l’état de l’objet ? Si oui, pourriez-vous me fournir des conseils ou une méthode pour y parvenir ?

Je vous remercie pour votre compréhension et votre aide continue.

Cordialement,
Elyass

Bonjour,

Il faudrait décrire un peu mieux votre processus metier, car il y a beaucoup de design patterns possibles.

Un processus Simplicité sert en général à parcourir différents objets metier. Il peut etre persistant si certaines activités sont dédiées à des profils distincts (process long avec rupture de saisie), ou sous forme de screenflow comme un assistant lorsque l’utilisateur est habilité à toutes ses activités (process uniquement en memoire de session).

Votre besoin semble plus simple : découvrir les données d’un objet suivants des étapes clés, donc on s’oriente généralement vers un state model mono-objet, plutôt qu’un processus. C’est l’objet metier qui représente directement votre processus via un champ “statut” énuméré.

Comme dans la demo :

  • une commande est un objet qui suit des étapes / cycle de vie : pending, validated, shipped… et par exemple le champ date de livraison n’est plus modifiable dans l’état validé, etc.
  • le processus de “prise de commande” est un screenflow, une aide à la saisie avec le choix du client puis fournisseur puis produit, qui aboutit à la commande pré-remplie dans son état initial en mise à jour.

Pour jouer sur les attributs de l’objet d’une Activité de type CRUD, il faut implémenter le hook postLock du processus (avant affichage de l’activité), qui connaît le contexte donc l’etape via context.getStep(), et travailler sur l’instance dédiée getGrant().getProcessInstance("myObject").

Mais si votre processus est mono-objet, il faut se limiter à un state-model, beaucoup plus simple, et gérer les données multiples du process par des relations 0,n vers l’objet (pieces jointes, bénéficiaires, historique des états…).

Bonjour François,

Je vous remercie pour votre réponse et vos suggestions. Permettez-moi de décrire plus en détail le contexte de mon processus métier actuel :

Actuellement, les utilisateurs doivent créer une fiche de traitement au sein de notre application. Cette fiche de traitement est basée sur un objet métier appelé “DataProcess”, qui contient un grand nombre de champs répartis sur neuf onglets différents (cf. capture ci-dessous). Cependant, chaque utilisateur a des besoins spécifiques et pourrait se contenter de remplir que certains champs de cet objet pour son propre processus.

Mon objectif est donc de simplifier la création de ces fiches de traitement pour les utilisateurs, en les guidant à travers le processus pas à pas. Plutôt que de leur présenter tous les champs et onglets à la création, je souhaite les diriger vers des étapes spécifiques où ils ne verront que les champs nécessaires à cette étape particulière. En d’autres termes, je cherche à transformer ces onglets en étapes d’un processus métier avec seulement certains champs à chaque étape.

Cela permettrait à chaque utilisateur de naviguer facilement à travers la création de la fiche de traitement en se concentrant uniquement sur les informations pertinentes à chaque étape.

Voici mon processus métier actuel :

J’espère que cette clarification aidera à mieux comprendre ma requête. Pourriez-vous, s’il vous plaît, me donner des conseils ou des orientations spécifiques pour implémenter cette approche ?

Je vous remercie pour votre précieuse assistance.

Cordialement,
Elyass

Merci pour ces précisions,

Effectivement, vos étapes s’apparentent à un screenflow d’aide à la saisie d’un formulaire complexe.
Vous pouvez donc utiliser un Processus :

  • dont la première activité est une création / New
  • les suivantes sont des mises à jour / Update du row_id à mapper sur la 1ere activité :
    1. soit sur le même objet et par code, vous pouvez récupérer l’étape et masquer les zones ou les attributs (hook pre/postLock décrit plus haut pour modifier l’instance getProcessInstance et les données de l’activité).
    2. soit sur des objets dédiés à chaque étape (même table physique) qui n’ont que les champs/zones nécessaires
  • L’activité finale peut contenir un Forward vers l’objet complet

Le 1) à l’avantage de n’avoir qu’un “gros” objet contextualisé par code.

@Override
public void preLock(ActivityFile context) {
	super.preLock(context);
	// any "update" after the "new"
	if (context.getActivity().getStep().equals("MY-STEP-2")) {
		// get the first "new" activity to get the created row_id
		Activity a = getActivity("MY-STEP-1"); 
		String rowId = getContext(a).getDataValue("Field", "row_id");
		// Force current activity to update this record
		context.setDataFile("Field", "row_id", rowId);
		// Simplify object definition
		ObjectDB o = getGrant().getProcessInstance("MyBigObject");
		o.getField("x").setVisibility(ObjectField.VIS_HIDDEN);
		o.getFieldArea("MyBigObject-1").setVisible(false);
		// ...
	}
	// else STEP-3 ...
}

Le 2) à l’avantage de n’avoir que des objets allégés paramétrés et sans code (le row_id pouvant se passer par paramétrage dans les activités suivantes :
Group=Field, Name=row_id, Value = [STEP-1.Field.row_id].

https://docs.simplicite.io/lesson/docs/core/businessworkflow-code-hooks

Voir la démo pour le forward final.

1 Like

Bonjour François,

Je vous remercie pour votre réponse détaillée !

J’ai bien compris votre suggestion d’utiliser un processus, dont la première activité serait une création (New), suivie de mises à jour (Update) du row_id mappé sur la première activité. Cependant, j’ai quelques questions supplémentaires sur la mise en œuvre de cette logique, en particulier en ce qui concerne le code à utiliser dans un objet process.

Pourriez-vous m’expliquer où et comment implémenter cette logique dans le code d’un objet process ? J’ai constaté que le hook “preLock()” n’est pas reconnu lorsque j’essaie de l’implémenter dans le code de mon objet métier (ObjectDB).
Y a-t-il des spécificités ou des différences dans la façon dont ce hook doit être utilisé dans un objet process par rapport à un objet métier pour gérer la logique que vous avez suggérée ?

Je vous remercie de prendre le temps de clarifier ces points.

Cordialement,
Elyass

pre/post-lock/validate/cancel/instanciate… sont des hooks du processus transverse à toutes les activités, rien à voir avec l’objet d’une activité donnée.

Il faut ouvrir la définition du Processus > bouton Edit code, puis implémenter les hooks héritant de Processus et non de ObjectDB :

public class MyProcessName extends Processus

https://docs.simplicite.io/lesson/docs/core/businessworkflow-code-hooks

Merci François pour ce retour.

Cependant, lorsque j’ouvre la définition de mon processus, je ne trouve pas le bouton “Edit code” mentionné dans votre réponse (cf. capture ci-dessous). Il semble que je ne puisse pas accéder à l’éditeur de code pour mon objet process.

Serait-il possible de m’indiquer où je peux trouver cet outil d’édition de code pour les objets process ? Ai-je besoin de certaines autorisations ou configurations spécifiques pour y accéder ?

Merci beaucoup pour votre aide.

Cordialement,
Elyass

La fonction processScriptEdit-A de l’objet BPMProcess est habilitée à ADMIN et DESIGNER.
Vérifiez que vous êtes bien dans un de ces profils, à priori oui sinon vous n’auriez pas ce menu.

De plus d’après votre copie d’écran, vous avez placé votre process dans un module système WorkflowUser qui interdit de modifier le code.

Il convient de mettre l’ensemble de vos paramétrages dans des modules métier, et ne modifier les modules système que si vous avez de bonnes raisons de la faire / et sous notre validation ou accord.
Tout ce qui ne sera pas dans une module métier, ne sera pas livrable.

Avez vous suivi une formation ? sinon je vous conseille de vous y inscrire si vous avez besoin d’une assistance plus fournie sur ces sujets élémentaires.

Je vous remercie pour votre réponse et vos précieuses indications.

Effectivement j’ai oublié de placer mon porcessus dans le bon module ce qui a causé ce problème. Du coup le soucis est réglé, désolé pour la confusion.
J’ai également vérifié mes autorisations, et je suis bien dans le profil DESIGNER, donc c’est OK de ce coté là.

Merci encore pour votre assistance précieuse.

Cordialement,
Elyass

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