lunes, 2 de julio de 2012

Programación BOL/GenIL. Crear nuevo bloque (5/7)

Continuamos con la creación del bloque. 
Vamos ahora a configurar la parte de webui para que nuestra clase sea visible mediante un bloque.

Conocido el componente a ampliar es necesario crear una nueva vista y asignarla al componente y grupo de pantallas. Hay que redefinir los métodos de la vista y crear nuevos eventos para que el bloque se comporte como deseamos. También hay que relacionar la vista con el GUID del objeto raíz. En este punto vamos a crear la vista mediante el asistente.

Entramos en la transacción BSP_WD_CMPWB en el componente que nos interesa. Para este caso vamos a ampliar las tareas por lo que nuestro componente es el BT125H_TASK. Pinchamos en la opción "Browser de modelo BOL". Si hemos realizado bien la configuración desplegando el objeto raiz deberíamos ver nuestro componente. 

Vamos a crear ahora la vista. 
Para crear la vista utilizamos el asistente y debemos incluir el objeto con el que vamos a relacionar la tabla. Este objeto nos aparece también en los objetos raiz del browser de modelo BOL. Debemos elegir el que nos convenga. En este caso concreto el que nos interesa el el objeto BTOrder.
Vamos al "Browser de estructura de componente" y en las vistas presionamos el botón derecho y crear. Nos muestra un asistente. En el primer paso debemos asignarle un nombre a la vista. Personalmente me gusta empezarlos por Z pero el nombre del completamente es libre. En el paso siguiente de nodos modelos asignamos nuestro nodo Root y el nodo con el que enlaza que hemos decidido que sea BTOrder:




En el paso de nodos de valor no indicamos nada. Pásamos al paso de atributos modelo.
Aqui presionamos el botón + () del asistente. Nos aparece una pantalla con los nodos que hemos introducido en el paso de nodos modelo con todos sus campo.

Seleccionamos los campos que queremos que aparezcan en la vista. Por norma deben ser todos los de la tabla Z y se debe incluir el campo de relación con el objeto estándar. En este paso es posible que algún campo genere conflicto de nombres. En caso de que se nos muestre un conflicto de nombres simplemente cambiamos el nombre del campo, por ejemplo poniendole una Z delante.

Se nos muestra una lista con todos los campos seleccionados. Pasamos al siguiente paso y continuamos sin indicar nada.
Seguimos con el paso de "crear enlaces para controlador custom". En este caso vamos un poco a ciegas. Tenemos que encontrar la relación entre el nodo de contexto BTOrden con los datos de la actividad (o los objetos que nos interese). Con un poco de sentido común y ayuda de MR. Google encontraremos la relación correcta. Siempre tenemos la opción de prueba-error. Una vez decidamos continuamos y debemos seleccionar el tipo de vista. Para nuestro caso nos interesa una vista de tabla, que sea confirgurable y modificable. Estos son los datos:


Presionamos continuar y se nos presenta el resumén de la configuración por si queremos cambiar algo. Presionamos finalizar y tenemos la vista creada.

Ya tenemos nuestra vista creada y relacionada con el componente. Vamos a publicarla. Para ello tenemos que añadir la vista al ViewSet que nos interese. Vamos al "Editor de repository en tiempo de validez" y presionamos el botón de modificar. En este caso vamos a modificar el ViewSet TaskOVViewset. En el viewArea presionamos el botón derecho y añadimos nuestra vista.
A continuación hacemos doble click en el viewSet y vamos a la pestaña de configuración. Añadimos la vista a los bloques que ya son visibles. Este paso lo podemos hacer en el WebGUI.
Volvemos al "Browser de estructura del componenete" y hacemos doble click en la vista. En la pestaña de configuración mostramos los campos que nos interesen.

Con esto nuestra vista está visible en web. En el siguiente post veremos como hacer que se comporte como nos interesa.

Relacionado:
Programación BOL/GenIL (1/.)
Programación BOL/GenIL (2/.)
Programación BOL/GenIL (3/.)
Programación BOL/GenIL (4/.)
Programación BOL/GenIL (6/.)


lunes, 4 de junio de 2012

Programación BOL/GenIL Crear nuevo bloque (4/7)

Seguimos con la programación BOL/GenIL y ahora vamos a ver que necesitamos para que la clase que hemos creado pueda crear, borrar y modificar entradas

  • Creación de entradas
    Voy a intentar que la creación de entradas sea de la forma más sencilla posible, con los campos clave crearemos la entrada en la tabla y luego volvemos a recuperar la tabla en los objetos. Debemos ampliar el método IF_GENIL_APPL_INTLAY~CREATE OBJECTS
    DATAls_parameters TYPE crmt_name_value_pair,
         ls_estructura
    TYPE ztabla_bol,
         lt_request_obj 
    TYPE crmt_request_obj_tab..

    * Creo una entrada en la tabla con los datos que van en la tabla de parámetros
      
    READ TABLE it_parameters INTO ls_parameters WITH KEY name = 'ACT_GUID'.
      
    IF sy-subrc 0.
        ls_estructura
    -act_guid ls_parameters-value.
      
    ENDIF.
      
    READ TABLE it_parameters INTO ls_parameters WITH KEY name = 'ID'.
      
    IF sy-subrc 0.
        ls_estrucutra
    -id ls_parameters-value.
      
    ENDIF.

    * Inserto la entrada en la tabla
      
    INSERT ztabla_bol FROM ls_estrucutra.

      
    me->if_genil_appl_intlay~get_objectsit_request_objects lt_request_obj
                                           iv_root_list       
    iv_root_list ).
  • Modificación de datos
    Para modificar los datos primero es necesario bloquearlos, para eso ampliaremos el método IF_GENIL_ALTERNATIVE_DSIL~LOCK_OBJECTS y luego modificarlos ampliando el método IF_GENIL_APPL_INTLAY~MODIFY_OBJECTS
    • Método IF_GENIL_ALTERNATIVE_DSIL~LOCK_OBJECTS
      El objetivo de este método es bloquear el objeto para que no pueda ser modificado en el mismo momento por otra sesión. Realmente del bloqueo se encarga el objeto al que está asociado nuestro bloque, en este caso una tarea. Por lo tanto lo único que necesitamos es que el método informe de que todo es OK.
      FIELD-SYMBOLS <ls_object> LIKE LINE OF ct_object_list.

        
      LOOP AT ct_object_list ASSIGNING <ls_object>.
          <ls_object>
      -success abap_true.
        
      ENDLOOP.
    •  Método IF_GENIL_APPL_INTLAY~MODIFY_OBJECTS
      Este método obtiene los campos modificados y modifica la BD. Si tenemos datos obligatorios en este método también podemos controlarlos para no modificar la BD si no se están informando.
      DATAlv_objeto TYPE REF TO if_genil_cont_root_object,
           lv_id 
      TYPE ztabla_bol-id,
           lv_props_obj 
      TYPE REF TO if_genil_obj_attr_properties,
           lt_changed_attr 
      TYPE crmt_attr_name_tab,
           ls_attributes   
      TYPE zestructura_bol,
           ls_objeto
      TYPE ztabla_bol.

        
      FIELD-SYMBOLS<new> TYPE simple,
                     <old> 
      TYPE simple,
                     <name> 
      TYPE name_komp.

        lv_expo 
      iv_root_list->get_first( ).

        
      WHILE lv_objeto IS BOUND.

      *   Comprobamos si han habido modificaciones
          
      IF lv_expo->get_delta_flag( ) = if_genil_cont_simple_object=>delta_changed.
      *     Obtenemos las propiedades de los atributos
            lv_props_obj 
      lv_expo->get_attr_props_obj( ).
      *     Comprobamos cuales se han modificado
            
      CALL METHOD lv_props_obj->get_name_tab_4_property
              
      EXPORTING
                iv_property 
      if_genil_obj_attr_properties=>modified
              
      IMPORTING
                et_names    
      lt_changed_attr.

      *     ID
            
      CALL METHOD lv_objeto->get_key
              
      IMPORTING
                es_key 
      lv_id.

      *     Atributos de la estrucutra
            
      CALL METHOD lv_objeto->get_attributes
              
      IMPORTING
                es_attributes 
      ls_attributes.

      *     Obtengo la entrada en la tabla
            
      SELECT SINGLE INTO ls_objeto
              
      FROM ztabla_bol
              
      WHERE id lv_id.

            
      LOOP AT lt_changed_attr ASSIGNING <name>.
              
      ASSIGN COMPONENT  <name> OF STRUCTURE ls_objeto TO <old>.
              
      ASSIGN COMPONENT <name> OF STRUCTURE ls_attributes TO <new>.
              <old> 
      <new>.
            
      ENDLOOP.

            
      UPDATE ztabla_bol FROM ls_objeto.

          
      ENDIF.

          lv_objeto
      iv_root_list->get_next( ).
        
      ENDWHILE.
    • Borrado de entradas
      Para borrar simplemente obtendremos el ID y borramos sin más. Hay que ampliar el método IF_GENIL_APPL_ALTERNATIVE_DSIL~DELETE_OBJECTS
      DATAlv_id TYPE ztabla_bol-id.
        
      FIELD-SYMBOLS<obj> TYPE crmt_genil_obj_inst_line.

        
      LOOP AT ct_object_list ASSIGNING <obj>.
      * Obtengo el ID de la tabla
          
      CALL METHOD cl_crm_genil_container_tools=>get_key_from_object_id
            
      EXPORTING
              iv_object_name 
      <obj>-object_name
              iv_object_id   
      <obj>-object_id
            
      IMPORTING
              es_key         
      lv_id.

      * Borro la entrada en la tabla
          
      DELETE FROM ztabla_bol WHERE id lv_id.

        
      ENDLOOP.
Con esto finalizamos las modificaciones en la clase de control de nuestro nuevo bloque

Relacionado:
Programación BOL/GenIL (1/.)
Programación BOL/GenIL (2/.)
Programación BOL/GenIL (3/.)
Programación BOL/GenIL (5/.)  
Programación BOL/GenIL.(7/7)

viernes, 4 de mayo de 2012

Programación BOL/GenIL. Crear nuevo bloque (3/7)

Siguiendo los post de programación GenIL vamos un paso más allá modificando nuestra clase para darle la funcionalidad que necesitamos.

La clase que hemos creado debe heredar obligatoriamente de la clase CL_CRM_GENIL_ABSTR_COMPONENT2. Con esto nos aseguramos que tenemos todos los métodos necesarios para su buen funcionamiento. Si no hiciesemos esto las llamadas desde el WebUI nos provocarían dumps continuamente.

Vamos a ver paso a paso que tenemos que ampliar en esta clase, en este primer post como obtener datos

  • Obtención de objetos y modelos
    Lo primero que necesitamos es obtener los objetos y modelos que hemos definido en las diferentes tablas. Los métodos a redefinir los siguientes
     
    • Método IF_GENIL_APPL_MODEL~GET_MODEL
      Debemos obtener los modelos de la tabla correspondiente. Insertar el siguiente código:

      SELECT * FROM ztabla_modelo
      INTO CORRESPONDING FIELDS OF TABLE rt_relation_det.  

       
    • Método IF_GENIL_APPL_MODEL~GET_OBJECT_PROPS
      Debemos obtener los modelos de la tabla correspondiente. Insertar el siguiente código:

      SELECT * FROM ztabla_objetos
      INTO CORRESPONDIG FIELDS OF TABLE rt_obj_props.

       
    • Método IF_GENIL_APPL_INTLAY~GET_OBJECTS.
      Este método transforma la entrada interna del objeto en un objeto de la BD. Insertar el siguiente código.

      DATA: lr_object TYPE  REF TO if_genil_container_object,
            lr_msg_cont TYPE REF TO cl_crm_genil_global_mess_cont,
            lv_name_obj TYPE ztabla-id,
            lr_attr_props TYPE REF TO if_genil_obj_attr_properties,
            l_result TYPE ztabla,
            lv_name TYPE crmt_ext_obj_name.
      * Cogemos la primera entrada de la tabla
      lr_object = iv_root_list->get_first( ).
      lr_msg_cont ?= iv_root_list->get_global_message_container().
      WHILE lr_object IS BOUND.
        lv_name = lr_object->get_name( ).
        IF lr_object->check_attr_requested( ) = abap_false.
          CALL METHOD lr_object->get_key
            IMPORTING
      es_key = lv_name_obj.

          SELECT SINGLE * FROM  ztabla
            INTO CORRESPONDING FIELDS OF l_result
            WHERE id = lv_name_obj.

          lr_object->set_attributes( l_result ).
          lr_attr_props = lr_object->get_attr_props_obj( ).
          lr_attr_props->set_all_properties( if_genil_obj_attr_properties=>changeable ).
        ENDIF.
        lr_object = iv_root_list->get_next( ).
      ENDWHILE.
  •  Selección de datos
    Para la selección de datos es necesario definir en primer lugar un tipo local mediante el botón para poder realizar búsquedas por rangos. El tipo se define de la siguiente manera:
    TYPES: BEGIN OF ty_general_rng,
      sign TYPE bapisign,
      option TYPE bapioption,
      low TYPE string,
      high TYPE string,
    END OF ty_general_rng.
    TYPES: tt_general_rng TYPE STANDARD TABLE OF ty_general_rng.

    A continuación redefinimos el siguiente método:
    • Método IF_GENIL_APPL_INTLAY~GET_DYNAMIC_QUERY_RESULT
      Para hacer la selección se realizará un select con todos los parámetros de la tabla asignando los parámetros a rangos. En el ejemplo solo filtro por un campo pero su puede utilizar cualquiera de la tabla. Hay que implementar el siguiente código.

      DATA:lr_object TYPE REF TO if_genil_cont_root_object,
           lt_result TYPE TABLE OF zestructura,
           lv_dyn_where TYPE string,
           lv_len TYPE i,
           ls_range TYPE tt_general_rng.
      * Variables para la búsqueda
      DATA: lt_variable TYPE tt_general_rng.
      FIELD-SYMBOLS: <fs_result> TYPE zestructura,
                     <fs_selection_range> TYPE genilt_selection_parameter.
      *Se recorren los parámetros
      LOOP AT it_selection_parameters[] ASSIGNING <fs_selection_range>
        MOVE: <fs_selection_range>-sign TO ls_range-sign,
              <fs_selection_range>-option TO ls_range-option,
              <fs_selection_range>-low TO ls_range-low,
              <fs_selection_range>-high TO ls_range-high.
        CASE <fs_selection_range>-attr_name.
          WHEN 'NOMBRE_CAMPO'.
            APPEND ls_range TO lt_variable[].
        ENDCASE.
        CLEAR ls_range.
      ENDLOOP.
      *Obtengo los datos de la tabla.
      SELECT * FROM ztabla INTO TABLE lt_result
        WHERE id IN lt_id
          AND campò IN lt_variable.

      CHECK LINES ( lt_result[] ) > 0.
      * Asigno el resultado
      LOOP AT lt_result ASSIGNING <fs_result>. 
        lr_object = iv_root_list->add_object( iv_object_name = 'Root'

        is_object_key = <fs_result>-id ).
        CHECK lr_object IS BOUND.
        lr_object->set_query_root( abap_true ).
      ENDLOOP.

En el siguiente post veremos como crear, modificar y borrar entradas.

Relacionado:
Programación Bol/GenIL (1/.)
Programación Bol/GenIL (2/.)
Programación Bol/GenIL (4/.)
Programación Bol/GenIL (5/.)   
Programación BOL/GenIL (6/.)