-
Notifications
You must be signed in to change notification settings - Fork 0
Home
El objetivo de este motor de aprobación es ser lo más genérico posible al proyecto que se este usando, por ello dispone de BADIs para poder cambiar estados de aprobación, aprobadores, etc. Además de un sistema de configuración sencillo para ir añadiendo o modificando workflow.
El motor esta desarrollando enteramente en ABAP Orientado a Objetos.
Las características que actualmente tiene el motor son:
- Configuración mediante tablas de los worflows y pasos que va a tener.
- Clase principal donde es muy sencillo iniciar un workflow, modificar sus datos y realizar aprobaciones.
- BADIs para poder cambiar aprobadores, estados o realizar procesos una vez se ha grabado el workflow.
- Dispone de un sistema de estado que es flexible, es decir, se puede indicar que el estado A puede ir al B o al C, a través de la BADIs se podrá determinar si tiene que ir al B o al C. En caso de un workflow normal que tiene los pasos A->B->C no es necesario implementar nada ya que todo esta automátizado.
- Se pueden crear workflow de tipo borrador.
- Log de modificaciones donde se puede saber al detalle cualquier cambio que se hace en el workflow.
- Clase de búsqueda que permite buscar datos de los workflow por casi cualquier campo del modelo de datos. Dicha clase hace uso de CDS para que las búsqueda en sistema HANA sea lo más optima posible.
Desde el menú de ámbito ZWFE es posible acceder a toda la configuración del motor:
Actualmente los backups no están implementando del motor debido a que para el proyecto que se crea el funcionamiento no va por usuarios nominales, va por roles.
Los Owners es una figura que indica que permite indicar quien serán los responsables del paso. Dentro de la transacción ZWFE_T005 podemos tener algo como lo siguiente:
En esta imagen se ven que hay distintos owners que luego se asignarán a los distintos pasos de los workflows configurados.
En la transacción ZWFE_T006 es donde se indica los aprobadores del paso, puede haber tantos aprobadores como se quiera. El aprobador puede ser un usuario nominal, email o cualquier otra cosa que permita determinar quien tiene que aprobar.
Para el proyecto de donde proviene la imagen, el aprobador es un rol. Dicho rol esta asignados a usuarios. Entonces la aplicación que llama al motor lo que hace primero es buscar el rol que tiene el usuario, y con el rol busca cuales son los workflows activos con dicho rol.
En la transacción ZWFE_T002 es donde se configuran todos los pasos que pueden ser usados por los workflow que se configuren:
Será en el flujo de pasos del workflow donde se indicará cual de ellos será el paso inicial, completado, etc.
Dentro de la transacción ZWFE_WORKFLOW, que por detrás tiene un cluster de vista, es donde se configura el workflow y como se va comportar:
En esta pantalla inicial es donde se parametrizan los distintos workflow que se quieran utilizar. Si se selecciona sobre uno de ellos y se pulsa sobre la carpeta Status:
Es donde se indicará el owner del status y cual va ser su comportamiento: inicial, borrador, completado, etc.
Si selecciona un status y se pulsa sobre la carpeta Flow status se configura a que estados puede ir:
Cuando el paso E001 se aprueba el motor mirará cual es su siguiente estado, que no este indicado como rechazado, que en este caso es el COMPL. Y como esta estado esta marcado como Completado el Worflow terminará.
En el cluster de vistas no hay ninguna verificación de la consistencia de los datos del workflow. Esta validación se realizará en el momento que se instance la clase que gestionará el workflow. Donde en el caso de los estados realizará las siguientes validaciones:
- Tiene que haber un, solo uno, estado inicial marcado.
- Que no haya status completados marcados. Puede haber varios status completados marcados.
- Que no haya status rechazados marcados. Puede haber varios status rechazados marcados.
En el apartado de utilidades tenemos:
- ZWFE_R_DEL_ALL_WF_ID --> Permite el borrado completo de un workflow a partir de su ID. Este programa se creo para borrar pruebas que se iban haciendo, pero puede usarse para el borrado de históricos.
Las clases que deben usar en los proyectos son dos:
-
ZCL_WFE_WORKFLOW_ENGINE encapsula la funcionalidad del motor y es la que se usará para inciar workflow, actualizarlo y aprobarlo/rechazarlo. Los métodos principales son:
- NEW_WORKFLOW --> Crea un nuevo workflow. Se le pasará el nombre del workflow, los valores, si se quiere en modo borrador o normal.
- CONTINUE_WORKFLOW_STEP --> Realiza la aprobación o rechazo de un Workflow. Se le pasa el ID del workflow y el paso a realizar(los pasos posibles están indicados en la interface ZIF_WFE_DATA=>CS_WF_PROCESS-STEP_RESULT. Donde tenemos dos campos que son: APPROVE o REJECT).
- UPDATE_VALUES --> Actualiza los valores del workflow. Se le pasa el ID del worlfow y sus valores. Dentro de los métodos indicados hay un parámetro, IV_PROCESS_USER, que permite indicar el usuario real de quien realiza el proceso. Esto esta motivado porque este motor nació de un proyecto donde el usuario de conexión de SAP desde UI5 era genérico, por lo tanto, nunca se sabía quien realmente estaba creando, modificando o aprobando. Esto hizo que este parámetro (que se le pasaba el email del portal donde estaba la aplicación UI5) permitiese guardar el usuario real en cada acción.
-
ZCL_WFE_MODEL_DATA_QUERY clase permite buscar en el modelo de datos los workflow casí por cualquier campo. En la mayoría de métodos hay un parámetro llamado IT_PARAMS_SL donde se le pasan los campos y sus valores a buscar. Este parámetro se basa en la estructura RSPARAMSL_255 que se usa en la opción WITH SELECTION-TABLE de la sentencia SUBMIT. Los métodos son:
- GET_ALL_WF_ID_DATA --> Busca toda la información del workflow a partir de un rango de ID
- GET_ALL_DATA --> Busca toda la información del worflow filtrando por casi todos los campos del modelo.
- GET_HEADER_DATA --> Busca toda la información de cabecera filtrando por casi todos los campos del modelo.
- GET_VALUES_DATA --> Busca toda la información de los valores filtrando por casi todos los campos del modelo.
- GET_STEPS_DATA --> Busca toda la información de los pasos filtrando por casi todos los campos del modelo.
- GET_STEPS_APPROVERS_DATA --> Busca toda la información de los aprobadores de los pasos filtrando por casi todos los campos del modelo.
- GET_HEADER_DATA --> Busca toda la información de cabecera filtrando por casi todos los campos del modelo.
Los campos que se pueden usar para el filtrado de datos están definidos en la interface ZIF_WFE_DATA=>CS_MODEL_DATA, en cada una de las estructura hay una llamada FIELDS, ejemplo: ZIF_WFE_DATA=>CS_MODEL_DATA-HEADER-FIELDS donde están los campos que se puedan usar.
El diagrama UML de clases es el siguiente:
El funcionamiento se explicará mediante ejemplo que es donde mejor se entienden. Aún así, en el programa "ZWFE_R_EXAMPLE_CALLS" están los ejemplos aquí listados.
DATA(lo_wf) = NEW zcl_wfe_workflow_engine( ).
lo_wf->new_workflow(
EXPORTING
iv_workflow = 'MY_DATA'
iv_process_user = '[email protected]'
it_values = VALUE #( ( field = 'MATERIAL' value = '22434' )
( field = 'CUSTOMER' value = '000223E' )
( field = 'CSR' value = '01223030' )
( field = 'AM' value = '22200' )
( field = 'KUNNR' value = '2343434' )
( counter = 1 field = 'CHEM_COMP_CHEMICALID' value = '5' )
( counter = 1 field = 'CHEM_COMP_MIN' value = '1' )
( counter = 1 field = 'CHEM_COMP_MAX' value = '5' )
( counter = 1 field = 'CHEM_COMP_UNIT' value = '%' )
( counter = 2 field = 'CHEM_COMP_CHEMICALID' value = '9' )
( counter = 2 field = 'CHEM_COMP_MIN' value = '10' )
( counter = 2 field = 'CHEM_COMP_MAX' value = '15' )
( counter = 2 field = 'CHEM_COMP_UNIT' value = 'KG' )
)
iv_draft = abap_false
IMPORTING
ev_wf_id = DATA(lv_wf_id)
et_return = DATA(lt_return) ).
WRITE:/ lv_wf_id.
DATA(lo_wf) = NEW zcl_wfe_workflow_engine( ).
lo_wf->update_values(
EXPORTING
iv_wf_id = '005056010BFD1EDBB58801A43D0D20BD'
it_values = VALUE #( ( field = 'STATUS_MAT' value = '05' ) )
iv_process_user = '[email protected]'
IMPORTING
et_return = DATA(lt_return) ).
DATA(lo_wf) = NEW zcl_wfe_workflow_engine( ).
lo_wf->continue_workflow_step(
EXPORTING
iv_wf_id = '005056010BFD1EDBBAC345CB1176C0BD'
iv_step_result = zif_wfe_data=>cs_wf_process-step_result-approve
iv_process_user = [email protected]'
IMPORTING
et_return = DATA(lt_return_continue)
ev_wf_completed = DATA(lv_wf_completed) )
DATA(lo_query) = NEW zcl_wfe_model_data_query( ).
lo_query->get_all_data(
EXPORTING
it_params_sl = VALUE #( ( selname = zif_wfe_data=>cs_model_data-header-fields-workflow kind = 'S' sign = 'I' option = 'EQ' low = 'PROFILE' )
( selname = zif_wfe_data=>cs_model_data-header-fields-wf_status kind = 'S' sign = 'I' option = 'EQ' low = zif_wfe_data=>cs_wf_process-wf_status-active )
( selname = zif_wfe_data=>cs_model_data-steps_approvers-fields-approver kind = 'S' sign = 'I' option = 'EQ' low =
'US_XXXX_APPROVALS_CHEMIST' )
( selname = zif_wfe_data=>cs_model_data-values-fields-field kind = 'S' sign = 'I' option = 'EQ' low = 'KUNNR' )
( selname = zif_wfe_data=>cs_model_data-values-fields-value kind = 'S' sign = 'I' option = 'EQ' low = '2343434' ) )
IMPORTING
et_all_data = DATA(lt_all_data)
et_header = DATA(lt_header)
et_steps = DATA(lt_steps)
et_steps_approvers = DATA(lt_steps_approvers)
et_values = DATA(lt_values) ).
DATA(lo_query) = NEW zcl_wfe_model_data_query( ).
lo_query->get_all_wf_id_data(
EXPORTING
it_r_wf_id = VALUE #( ( sign = 'I' option = 'EQ' low = '005056010BFD1EDC8097BEA0C0B720BD' ) )
IMPORTING
et_header = DATA(lt_header)
et_steps = DATA(lt_steps)
et_steps_approvers = DATA(lt_steps_approvers)
et_values = DATA(lt_values) ).
DATA(lo_query) = NEW zcl_wfe_model_data_query( ).
lo_query->get_changelog_data(
EXPORTING
it_r_wf_id = VALUE #( ( sign = 'I' option = 'EQ' low = '005056010BFD1EDBB58801A43D0D20BD' ) )
IMPORTING
et_changelog_data = DATA(lt_changelog_data) ).
Para poder modificar el funcionamiento del workflow y evitar tener que tocar las tripas del motor, cumpliendo la premisa de ser independiente al proyecto, se ha creado el enhacement spot ZWFE_ENHACEMENT_WORKFLOW que contiene, al menos de momento, dos BADIs que son:
- ZWFE_BADI_ENGINE -> Actualmente no tiene funcionalidad alguna pero en un futuro es posible que se utilice dentro de la clase ZCL_WF_ENGINE, que como se ha visto en el funcionamiento, es la clase que gobierna todo el motor.
- ZWFE_BADI_WF_MODEL -> Esta BADI actualmente esta implementada en la clase ZCL_WFE_WORKFLOW, clase con las tripas del motor, tiene una serie de métodos que nos permiten realizar acciones sobre los workflow. Los métodos que tienen son:
- CHANGE_STEP_APPROVERS --> Permite cambiar el aprobador de un paso en el proceso de aprobación/rechazo. En este método tendremos como parámetro:
- Status determinado
- Valores del workflow
- Aprobadores determinados para ese status.
- POST_SAVE_WORKFLOW --> Se lanza una vez el workflow ha sido grabado con éxito. Este método como parámetro esta la propia clase que se esta usando donde se podrá recuperar los valores necesarios del workflow y realizar las acciones que se necesiten, como enviarlo mail, realizar notificaciones, etc.
- DETERMINE_NEXT_STATUS --> Se lanza en el proceso de aprobación/rechazo y permite indicar cual será el siguiente status. Este método solo tiene sentido usarse cuando hay más de un status configurado al status actual, el motivo es porque solo se puede ir al status indicado en el flujo configurado.
A este método tiene como parámetros:
- Status actual
- Valores del workflow
- Status siguientes
- Resultado del paso(si se rechaza o aprueba)
- CHANGE_STEP_APPROVERS --> Permite cambiar el aprobador de un paso en el proceso de aprobación/rechazo. En este método tendremos como parámetro:
En las BADIs creada tienen un filtro donde se le pasará el nombre del workflow. Esto hace que cada workflow tenga su propia BADI, simplificando las implementaciones al no mezclarse código en los métodos de distintos workflows.