miércoles, 17 de octubre de 2012

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

Para terminar con nuestro bloque es necesario que le pongamos los botones con el código necesario para realizar acciones. Los botones que vamos a crear son los de Insertar / Borrar y Modificar.

Para poder implementar los botones hay que definir atributos en la clase de implementación, definir los botones y los eventos controladores. En la clase de implementación hay que definir dos nuevos atributos, TB_BUTTON y GT_BUTTON. Estos serán los contenedores para nuestros botones. Definimos dos ya que así en modo visualización no tenemos opción de borrar o insertar y en modo modificación no tendremos el botón de modificar. Estos dos atributos deben definirse como atributos de instancia, públicos, y del tipo CRMT_THTMLB_BUTTON.

  • Botón Editar
    Para el funcionamiento del botón es necesario modificar el método DO_PREPARE_OUTPUT y crear el evento en la clase de implementación. El código a añadir en el método es el siguiente, habrá que añadir el código análogo para el resto de botones.:

    CLEAR: tb_button, ls_button.
    ls_button-text = 'Tratar lista'.
    ls_button-on_click = 'EDIT'.
    ls_button-enabled = me->view_group_context->is_view_in_display_mode( me ).
    APPEND ls_button TO tb_button.

    A continuación se crea el evento mediante el botón derecho en la carpeta de eventos. El nombre debe ser el mismo que hemos definido en el campo ls_button-on_click, en este caso "EDIT".
    El código a implementar en el evento es el siguiente:
    DATA: lr_tx TYPE REF TO if_bol_transaction_context,
      lr_entity TYPE REF TO cl_crm_bol_entity,
      lr_comp TYPE REF TO cl_bt125h_t_bspwdcomponen_impl.
    lr_comp ?= me->comp_controller.
    CHECK lr_comp IS BOUND.
    lr_entity ?= lr_comp->typed_context->btorder->collection_wrapper->get_current( ).

    CHECK lr_entity IS BOUND.
    IF lr_entity->lock( ) = abap_true.
      me->view_group_context->set_view_editable( me ).
    ENDIF.
    lr_entity ?= me->typed_context->root->collection_wrapper->get_first( ).
    WHILE lr_entity IS BOUND.
      lr_entity->lock( ).
      lr_entity ?= me->typed_context->root->collection_wrapper->get_next( ).
    ENDWHILE.

  • Botón insertar
    Al insertar creamos un nuevo ID en la tabla. Para esto se ha definido el método ZGET_ID en el nodo de contexto para obtener el nuevo ID.

    METHOD zget_id.
    DATA: lt_expos TYPE STANDARD TABLE OF zexpo_bol_st, 
          ls_expos LIKE LINE OF lt_expos,
          lv_id_old TYPE char10.
    FIELD-SYMBOLS <fs_expos> TYPE zexpo_bol_st.

    * Leo la tabla, ordeno y cubro huecos
    SELECT * INTO TABLE lt_expos FROM zexpos_bol.

    SORT lt_expos BY id ASCENDING.
    lv_id_old = '0000000001'.

    LOOP AT lt_expos INTO ls_expos.
      IF ls_expos-id = lv_id_old.
        lv_id_old = lv_id_old + 1.
        CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'       EXPORTING
            input = lv_id_old
          IMPORTING
            output = lv_id_old.
      ELSE.
        EXIT.
      ENDIF.

    ENDLOOP.
    ev_id = lv_id_old.

    ENDMETHOD.

    El método debe llevar un parámetro ev_id export de tipo char 10
    La implementación del evento es la siguiente:
    METHOD eh_oninsert.

    DATA : lr_entity TYPE REF TO cl_crm_bol_entity,

           lv_collection TYPE REF TO if_bol_bo_col,
           lr_comp TYPE REF TO cl_bt125h_t_bspwdcomponen_impl.

    DATA : lr_core TYPE REF TO cl_crm_bol_core,

           lr_fac TYPE REF TO cl_crm_bol_entity_factory,
           lt_params TYPE crmt_name_value_pair_tab,
           ls_params TYPE crmt_name_value_pair,
           lr_ent TYPE REF TO cl_crm_bol_entity,
           lv_cmp_guid TYPE crmt_object_guid.

    DATA lv_id TYPE zexpos_bol-id.


    lr_comp ?= me->comp_controller.

    CHECK lr_comp IS BOUND.
    lr_entity ?= lr_comp->typed_context->btorder->collection_wrapper->get_current( ).

    me->typed_context->root->deselect_all( ).


    IF lr_entity->is_changeable( ) = abap_true.

       lr_core = cl_crm_bol_core=>get_instance( ).
       lr_fac = lr_core->get_entity_factory( 'Root' ).
       TRY.
    * Para crear la entrada le paso el GUID de la relación
         lr_entity->get_property_as_value( EXPORTING iv_attr_name = 'CRM_GUID'
            IMPORTING ev_result = lv_cmp_guid ).

    * Obtengo el ID

         ls_params-name = 'ID'.
         me->typed_context->root->zget_id( IMPORTING ev_id = lv_id ).
         ls_params-value = lv_id.
         APPEND ls_params TO lt_params.
         ls_params-name = 'ACT_GUID'.
         ls_params-value = lv_cmp_guid.
         APPEND ls_params TO lt_params.
         lr_core->root_create( iv_object_name = 'Root'
         iv_create_param = lt_params
         iv_number = 1 ).

         me->root_query( ).

         me->eh_onedit( ).


       CATCH cx_crm_genil_model_error.

         EXIT.
       CATCH cx_sy_ref_is_initial.
      ENDTRY.
    ENDIF.

    ENDMETHOD.


  • Botón borrar:
    El evento de borrado comprueba si el objeto se puede bloquear y lo borra. El método es el siguiente:

    METHOD eh_ondelete.

     DATA: lr_core TYPE REF TO cl_crm_bol_core,
      lr_docflow TYPE REF TO cl_crm_bol_entity.

    lr_docflow ?= me->typed_context->root->collection_wrapper->get_current( ).
    CHECK lr_docflow IS BOUND.

    IF NOT lr_docflow->is_locked( ) EQ abap_true.
      lr_docflow->lock( ).
    ENDIF.

    CHECK lr_docflow->is_locked( ) EQ abap_true.
    lr_core = cl_crm_bol_core=>get_instance( ).

    lr_core->modify( ).
    lr_docflow->delete( ).

    lr_core = cl_crm_bol_core=>get_instance( ).
    lr_core->modify( ).

    ENDMETHOD.

Por último hay que retocar un poco el HTML de la página base. El código a incluir es el siguiente:

<%@page language="abap" %>
<%@extension name="thtmlb" prefix="thtmlb" %>
<%@extension name="chtmlb" prefix="chtmlb" %>
<%@extension name="bsp" prefix="bsp" %>
<thtmlb:areaFrameSetter toolbarButtons = "<%= controller->tb_button %>"
maxButtonNumber = "2"
displayMode = "<%= controller->view_group_context->is_view_in_display_mode( controller ) %>" />
<chtmlb:configTable actionsMaxInRow = "3"
allRowsEditable = "TRUE"
displayMode = "<%= controller->view_group_context->is_view_in_display_mode( controller ) %>"
downloadToExcel = "TRUE"
id = "Table1"
onRowSelection = "select"
personalizable = "TRUE"
selectedRowIndex = "<%= Root->SELECTED_INDEX %>"
selectedRowIndexTable = "<%= Root->SELECTION_TAB %>"
selectionMode = "<%= Root->SELECTION_MODE %>"
table = "//Root/Table"
usage = "ASSIGNMENTBLOCK"
visibleFirstRow = "<%= Root->VISIBLE_FIRST_ROW_INDEX %>"
visibleRowCount = "6"
width = "100%"
xml = "<%= controller->configuration_descr->get_config_data( ) %>"
actions = "<%= controller->gt_button %>"/>       


4 comentarios:

  1. Hola.

    Realmente estoy sufriendo con esto de agregar un bloque editable en el componente CGP_MAIN xD, antes de iniciar el ejemplo me gustaría saber si las entradas se grabarían en la tabla transparente al grabar la campaña o si se graban al instante al realizar la acción. Veo que se afecta a la tabla Z, no hay un commit o algo pero igual tengo mis dudas.

    ResponderEliminar
    Respuestas
    1. En este caso el grabado en la tabla Z es directo, si quieres que haya memoria intermedia seguro que hay alguna forma, pero no me he puesto a investigarla.

      Y tienes razón con esto se sufre mucho....

      Eliminar
  2. Ah uno de los ejemplos que hice fue con Simple Object BOL, pero no me permite borrar ni editar las entradas :(, solo puedo crear nuevos registros tanto en CRM WEB UI como en GENIL_MODEL_BROWSER al probar mi BOL. En ese ejemplo mi BOL se asignó al componente SO2. ¿Se puede hacer que las entradas sean editables?

    ResponderEliminar
    Respuestas
    1. En Web UI necesitas trabajar con el evento on_edit que lo tienes que llamar con el botón de editar. El ejemplo lo tienes desarrollado más arriba pero básicamente se trata de hacer el objeto editable con me->view_group_context->set_view_editable( me ).

      Eliminar