ABAPZXXHORAS

Pequeña aplicación que permite llevar un registro de las horas trabajadas por usuario y explotar los datos por las personas que lo necesites. ¡¡Muerte a los XLS!!

  1. REPORT Z_XX_PRG_HORAS.
  2. CONSTANTS c_vers TYPE string VALUE 'GHAS - v01.11.20250210'.
  3. *--[ 01.00.00          - Creacion del programa
  4. *--[ 01.01.00          - Programa customizado para proyecto
  5. *--[ 01.02.00 20241213 + Grupo de SuperUsers
  6. *--[                   + DES/Visar registros solo SuperUsers
  7. *--[                   + Anyaadido Vacaciones / Enfermedad / Planning General
  8. *--[ 01.02.01 20250110 + Colocados campos automaticos en la creación
  9. *--[                   + Anyaadido botón Fast Track
  10. *--[                   + Corregido BUG del INDICE
  11. *--[                   + Optimizada rutina de grabacion
  12. *--[                   + Inclusion de bloqueos de registros
  13. *--[                   + Optimizaciones generales
  14. *--[ 01.03.00          + Anyadido fichero de configuracion
  15. *--[ 01.04    20250113 + Correcciones varias y anyadido LAYOUT
  16. *--[ 01.05    20250114 + Anyadido nueva columna Tipo_Tarea
  17. *--[                   + Mejor gestion de bloqueos
  18. *--[ 01.06    20250116 + Mejoras + Copia Local + Lock Claves
  19. *--[ 01.07    20250123 + Pequenyas optimizaciones y correción de errores
  20. *--[ 01.08    20250130 + Anyadido boton copia hasta fecha final + weekday
  21. *--[ 01.09    20250205 + Opcion de visualizacion
  22. *--[ 01.10    20250206 + Anyadido en tabla BEGTIME y ENDTIME
  23. *--[ 01.11    20250210 + Anyadido llamada a JIRA
  24.  
  25. INCLUDE zgva_xx_i_zini_config_files.
  26.  
  27. INCLUDE Z_XX_I_HORAS_TOP.
  28. INCLUDE Z_XX_I_HORAS_CLS.
  29. INCLUDE Z_XX_I_HORAS_SEL.
  30. INCLUDE Z_XX_I_HORAS_EVE.
  31. INCLUDE Z_XX_I_HORAS_FRM.

Include: Z_XX_I_HORAS_TOP

  1. TABLES: t001.
  2. TABLES: sscrfields.  "<-- Para los botones en el PF-STATUS
  3.  
  4. FIELD-SYMBOLS  : <gfs_t_pay_data>   TYPE ANY TABLE.
  5.  
  6. *--[ Si, ya, se puede hacer dinámico, pero a veces es más rápido lo estático que
  7. *--[ la lógica de procesamiento...
  8. TYPES: begin of ty_has,
  9.            proyecto(90),
  10.            COL_01 type p LENGTH 6 DECIMALS 2,
  11.            COL_02 type p LENGTH 6 DECIMALS 2,
  12.            COL_03 type p LENGTH 6 DECIMALS 2,
  13.            COL_04 type p LENGTH 6 DECIMALS 2,
  14.            COL_05 type p LENGTH 6 DECIMALS 2,
  15.            COL_06 type p LENGTH 6 DECIMALS 2,
  16.            COL_07 type p LENGTH 6 DECIMALS 2,
  17.        end of ty_has,
  18.  
  19.        BEGIN OF ty_plan,
  20.          gjahr     TYPE  gjahr,
  21.          mes       TYPE  char20,
  22.          uname     TYPE  xubname,
  23.          uname_txt TYPE  text50,
  24.          dia_01    TYPE  char6,
  25.          dia_02    TYPE  char6,
  26.          dia_03    TYPE  char6,
  27.          dia_04    TYPE  char6,
  28.          dia_05    TYPE  char6,
  29.          dia_06    TYPE  char6,
  30.          dia_07    TYPE  char6,
  31.          dia_08    TYPE  char6,
  32.          dia_09    TYPE  char6,
  33.          dia_10    TYPE  char6,
  34.          dia_11    TYPE  char6,
  35.          dia_12    TYPE  char6,
  36.          dia_13    TYPE  char6,
  37.          dia_14    TYPE  char6,
  38.          dia_15    TYPE  char6,
  39.          dia_16    TYPE  char6,
  40.          dia_17    TYPE  char6,
  41.          dia_18    TYPE  char6,
  42.          dia_19    TYPE  char6,
  43.          dia_20    TYPE  char6,
  44.          dia_21    TYPE  char6,
  45.          dia_22    TYPE  char6,
  46.          dia_23    TYPE  char6,
  47.          dia_24    TYPE  char6,
  48.          dia_25    TYPE  char6,
  49.          dia_26    TYPE  char6,
  50.          dia_27    TYPE  char6,
  51.          dia_28    TYPE  char6,
  52.          dia_29    TYPE  char6,
  53.          dia_30    TYPE  char6,
  54.          dia_31    TYPE  char6,
  55.          total     TYPE  p LENGTH 10 DECIMALS 2,
  56.          cellcolor TYPE  lvc_t_scol,
  57.        END OF ty_plan,
  58.  
  59.        begin of ty_zxx_st_horas.
  60.   include STRUCTURE ZXX_HORAS.
  61. types: UNAME_TXT  Type  TEXT50,
  62.        PROYECTO_TXT Type  TEXT50,
  63.        TIPO_TXT Type  TEXT50,
  64.        MODULO_TXT Type  TEXT50,
  65.        ASIGNADO_TXT Type  TEXT50,
  66.        STATUS_TXT Type  TEXT50,
  67.        CELLTAB  Type  LVC_T_STYL,
  68.        FECHA_TXT type TEXT50,
  69.        end of ty_zxx_st_horas.
  70.  
  71. DATA: g_error        TYPE sy-subrc,
  72.  
  73.       g_okcode       TYPE sy-ucomm,
  74.       g_titulo(255),
  75.  
  76.       t_fcode        TYPE TABLE OF sy-ucomm,
  77.  
  78. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  79. *--[ Definiciones ALV
  80.       cc_01 type ref to cl_gui_custom_container,
  81.       cc_03 type ref to cl_gui_custom_container,
  82.       gs_layout      TYPE lvc_s_layo,
  83.       gs_variant     TYPE disvariant,
  84.  
  85.       gs_layout_02   TYPE lvc_s_layo,
  86.       gs_variant_02  TYPE disvariant,
  87.  
  88.       grid_01        TYPE REF TO cl_gui_alv_grid,
  89.       grid_02        TYPE REF TO cl_gui_alv_grid,
  90.       grid_03        TYPE REF TO cl_gui_alv_grid,
  91.  
  92.       t_tab_03       TYPE STANDARD TABLE OF ty_plan,
  93.       t_tab_has       TYPE STANDARD TABLE OF ty_has,
  94.  
  95.       t_tab_01       TYPE STANDARD TABLE OF ty_zxx_st_horas,
  96.       t_tab_del      TYPE STANDARD TABLE OF ty_zxx_st_horas,
  97.       t_tab_upd      TYPE STANDARD TABLE OF ty_zxx_st_horas,
  98.       l_tab_01       LIKE LINE OF t_tab_01,
  99.  
  100.       t_fcat_01      TYPE lvc_t_fcat,
  101.       t_fcat_02      TYPE lvc_t_fcat,
  102.       t_fcat_03      TYPE lvc_t_fcat,
  103.  
  104.       t_sort         TYPE lvc_t_sort,
  105.       t_sort_02      TYPE lvc_t_sort,
  106.  
  107.       gt_toolbar     TYPE  ui_functions,
  108.       gt_toolbar_has TYPE  ui_functions,
  109.       g_today        type sydatum,
  110.       g_save         TYPE xfeld,
  111.  
  112. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  113. *--[
  114.       end_of_Data(1).
  115.  
  116. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  117. *--[ CONFIG Section
  118.  
  119. types: begin of ty_config_estat,
  120.         CODIGO(20),
  121.         ICONO TYPE ICON_D,
  122.         color type c LENGTH 1,
  123.         Texto TYPE GUI_TEXT,
  124.       end of ty_config_estat,
  125.  
  126.       begin of ty_default,
  127.          field(40),
  128.          valor(120),
  129.       end of ty_default,
  130.  
  131.       Begin of ty_config,
  132.           ALV         type i,
  133.           SU          type RANGE OF XUBNAME,
  134.           URL         type c LENGTH 1023,
  135.           jira_URL     type c LENGTH 1023,
  136.           Days_Before type i,
  137.           ESTAT       type STANDARD TABLE OF ty_config_estat with NON-UNIQUE DEFAULT KEY,
  138.           OBJ         type REF TO zini_cl_config_files,
  139.           DATE_BEFORE type sy-datum,
  140.           DEF         type STANDARD TABLE OF ty_default with NON-UNIQUE DEFAULT KEY,
  141.           T_FEST      type range of numc4,
  142.           T_FESTfull  type range of numc08,
  143.           visu        type xfeld,
  144.        end of ty_config.
  145. data: data_config type ty_config.

Include Z_XX_I_HORAS_CLS

  1. CLASS lcl_event_handler DEFINITION FINAL.
  2.   PUBLIC SECTION .
  3.  
  4.     DATA: my_config TYPE ty_config.
  5.  
  6.     METHODS:
  7.  
  8.       handle_data_changed
  9.         FOR EVENT data_changed OF cl_gui_alv_grid
  10.         IMPORTING er_data_changed E_ONF4 E_ONF4_BEFORE E_ONF4_AFTER E_UCOMM,
  11.  
  12.       handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
  13.         IMPORTING e_object, " e_interactive,
  14.  
  15.       handle_hotspot for event HOTSPOT_CLICK of cl_gui_alv_grid
  16.          IMPORTING E_ROW_ID E_COLUMN_ID ES_ROW_NO,
  17.  
  18.       handle_menu_button
  19.         FOR EVENT menu_button OF cl_gui_alv_grid
  20.         IMPORTING e_object e_ucomm,
  21.  
  22.       handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
  23.         IMPORTING e_ucomm .
  24.  
  25. ENDCLASS.
  26.  
  27. DATA: G_event_01 TYPE REF TO lcl_event_handler,
  28.       G_event_has TYPE REF TO lcl_event_handler.
  29.  
  30. CLASS lcl_event_handler IMPLEMENTATION .
  31.  
  32. method handle_hotspot.
  33. *--[ E_ROW_ID Type  LVC_S_ROW
  34. *--[ E_COLUMN_ID  Type  LVC_S_COL
  35. *--[ ES_ROW_NO  Type  LVC_S_ROID
  36.  
  37.    case E_COLUMN_ID.
  38.  
  39.      when 'CODIGO'.
  40.           try.
  41.           data(l_Valor) = to_upper( t_tab_01[ ES_ROW_NO-ROW_ID ]-CODIGO ).
  42.           if l_Valor cp 'GESTIC-*'.
  43.             data(my_url) = CONV string( |{ my_config-jira_url }{ l_Valor }| ).
  44.             cl_gui_frontend_services=>execute( document = my_url ).
  45.           endif.
  46.  
  47.           CATCH cx_root.
  48.  
  49.           endtry.
  50.      when OTHERS.
  51.          clear sy-subrc.
  52.    endcase.
  53.  
  54. ENDMETHOD.
  55.  
  56.   METHOD handle_menu_button.
  57.     case my_config-ALV.
  58.     when 1.
  59.     CASE e_ucomm.
  60. *--[ Valores estadisticos
  61.       WHEN 'P020'.
  62.         LOOP AT my_config-estat INTO DATA(l_data).
  63.           e_object->add_function( fcode = |ES{ sy-tabix }| icon = l_data-icono  text = l_data-texto ).
  64. *        e_object->add_function( fcode = 'BOT03' icon = icon_sickness text = 'Enfermedad' ).
  65.         ENDLOOP.
  66. *--[ Parametrización
  67.       WHEN 'P010'.
  68.         e_object->add_function( fcode = 'P011' icon = icon_package_standard text = 'Proyecto' ).
  69.         e_object->add_function( fcode = 'P012' icon = icon_package_standard text = 'Módulo' ).
  70.         e_object->add_function( fcode = 'P016' icon = icon_package_standard text = 'Tipo Tarea' ).
  71.         e_object->add_function( fcode = 'P013' icon = icon_package_standard text = 'Estado' ).
  72. *        e_object->add_function( fcode = 'P014' icon = icon_user_breakpoint  text = 'Super Usuarios' ).
  73.         e_object->add_function( fcode = 'P015' icon = icon_user_breakpoint  text = 'Editar Config' ).
  74.     ENDCASE.
  75.     when 3.
  76.     endcase.
  77.   ENDMETHOD.
  78.  
  79.   METHOD handle_data_changed.
  80.  
  81.     LOOP AT er_data_changed->MT_deleted_rows INTO DATA(l_row).
  82.       READ TABLE t_tab_01 INDEX l_row-row_id INTO DATA(ax).
  83.       CHECK ax-indice NE 0.
  84.       APPEND ax TO t_tab_del.
  85.       CLEAR ax.
  86.       AT LAST.
  87.         g_save = abap_true.
  88.       ENDAT.
  89.     ENDLOOP.
  90. data: l_celltab type LVC_T_STYL.
  91.     LOOP AT er_data_changed->mt_inserted_rows INTO DATA(l_ins).
  92.  
  93. *        assign ('L_TAB_01-INDICE') TO FIELD-SYMBOL(<AX>).
  94. *        CALL METHOD er_data_changed->get_cell_value(
  95. *          EXPORTING
  96. *            i_row_id    = l_ins-row_id
  97. *            i_fieldname = CONV lvc_fname( 'INDICE' )
  98. *          IMPORTING
  99. *            e_value     = <ax> ). "<- Esto dará problemas...
  100.  
  101. *--[ Campos por defecto
  102.       LOOP AT my_config-def  INTO DATA(l_def).
  103.  
  104.        data(l_field) = |L_TAB_01-{ l_def-field }|.
  105.         assign (l_field) to FIELD-SYMBOL(<f_field>).
  106.         CALL METHOD er_data_changed->get_cell_value(
  107.           EXPORTING
  108.             i_row_id    = l_ins-row_id
  109.             i_fieldname = CONV lvc_fname( l_def-field )
  110.           IMPORTING
  111.             e_value     = <f_field> ). "<- Esto dará problemas...
  112.  
  113.         CHECK <f_field> IS INITIAL.
  114.         <f_field> = l_def-valor.
  115.         CALL METHOD er_data_changed->modify_cell
  116.           EXPORTING
  117.             i_row_id    = l_ins-row_id
  118.             i_fieldname = CONV lvc_fname( l_def-field )
  119.             i_value     = <f_field>.
  120.       ENDLOOP.
  121.  
  122.     ENDLOOP.
  123.  
  124.     LOOP AT er_data_changed->mt_good_cells INTO DATA(ls_good).
  125.       CLEAR ax.
  126.       READ TABLE t_tab_01 INDEX ls_good-row_id INTO ax.
  127.       IF ax-indice NE 0.
  128.         APPEND ax TO t_tab_upd.
  129.       ENDIF.
  130.  
  131. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  132. *--[ Hay que hacer más verificaciones, pero dejo esta como ejemplo
  133.       CASE ls_good-fieldname.
  134.         WHEN 'UNAME'.
  135.           IF ls_good-value IS INITIAL.
  136.             CALL METHOD er_data_changed->modify_cell
  137.               EXPORTING
  138.                 i_row_id    = ls_good-row_id
  139.                 i_fieldname = ls_good-fieldname
  140.                 i_value     = sy-uname.
  141.           ENDIF.
  142.         WHEN 'FECHA'.
  143.           IF sy-uname IN data_config-su.
  144.           ELSE.
  145.             DATA(l_datum) = CONV sydatum( ( CONV sydatum( ls_good-value ) ) + my_config-days_before ).
  146.             IF l_datum < sy-datum.
  147.               er_data_changed->add_protocol_entry( i_msgid     = '00'
  148.                                      i_msgty     = 'E'
  149.                                      i_msgno     = '398'
  150.                                      i_msgv1     = 'Fecha'
  151.                                      i_msgv2     = |{ ls_good-value }|
  152.                                      i_msgv3     = 'no permitida'
  153.                                      i_fieldname = ls_good-fieldname ).
  154.             ENDIF.
  155.           ENDIF.
  156. *--[ Inicializamos la fecha
  157.           IF ls_good-value+0(8) CO '0'.
  158.             CALL METHOD er_data_changed->modify_cell
  159.               EXPORTING
  160.                 i_row_id    = ls_good-row_id
  161.                 i_fieldname = ls_good-fieldname
  162.                 i_value     = sy-datum.
  163.           ENDIF.
  164.       ENDCASE.
  165.  
  166.       g_save = abap_true.
  167.  
  168. *      CALL METHOD er_data_changed->modify_cell
  169. *        EXPORTING
  170. *          i_row_id    = ls_good-row_id
  171. *          i_fieldname = CONV #( l_campo )
  172. *          i_value     = sy-uname.
  173. *
  174.     ENDLOOP.
  175.  
  176.   ENDMETHOD.
  177.  
  178.   METHOD handle_toolbar.
  179.  
  180.     case my_config-alv.
  181.     when 1.
  182.     IF sy-uname IN data_config-su.
  183.       DATA(l_modo) = abap_false.
  184.     ELSE.
  185.       l_modo = abap_true.
  186.     ENDIF.
  187.  
  188.     e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar
  189.                                   ( butn_type = 0
  190.                                     function = 'COPY'
  191.                                     icon = ICON_SYSTEM_COPY
  192.                                     text = ''
  193.                                     quickinfo = 'Copiar Seleccionados'
  194.                                     disabled  = data_config-visu )
  195.                                     ).
  196.    read table e_object->mt_toolbar index lines( e_object->mt_toolbar  ) into data(ax).
  197.    delete e_object->mt_toolbar index lines( e_object->mt_toolbar  ).
  198.    insert ax into e_object->mt_toolbar index 7.
  199.  
  200.         e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar
  201.                                   ( butn_type = 0
  202.                                     function = 'COPYP'
  203.                                     icon = ICON_SYSTEM_COPY
  204.                                     text = 'hasta fecha'
  205.                                     quickinfo = 'Copiar con modelo hasta fecha fin'
  206.                                     disabled  = data_config-visu )
  207.                                     ).
  208.  
  209. * Please, disperse, nothing to see here...
  210.    read table e_object->mt_toolbar index lines( e_object->mt_toolbar  ) into ax.
  211.    delete e_object->mt_toolbar index lines( e_object->mt_toolbar  ).
  212.    insert ax into e_object->mt_toolbar index 8.
  213.  
  214.     e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar
  215.  
  216.                                   ( butn_type = 2
  217.                                     function = 'P010'
  218.                                     icon = icon_configuration
  219.                                     text = 'Parametriziación'
  220.                                     quickinfo = 'Parametrización'
  221.                                     disabled  = l_modo ) ).
  222.  
  223.     IF lines( my_config-estat ) > 0.
  224.       e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar
  225.                                     ( butn_type = 2
  226.                                       function = 'P020'
  227.                                       icon = icon_configuration
  228.                                       text = 'Estadistico'
  229.                                       quickinfo = 'Valor Estadístico'
  230.                                       disabled  = abap_false ) ).
  231.     ENDIF.
  232.  
  233.     e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar
  234.                                   ( butn_type = 0
  235.                                     function = 'BOT01'
  236.                                     icon = icon_select_all
  237.                                     text = 'Visar'
  238.                                     quickinfo = 'Visar todos'
  239.                                     disabled  = COND #( WHEN DATA_config-visu = abap_true THEN abap_true else l_modo ) )
  240.  
  241.                                   ( butn_type = 0
  242.                                     function = 'BOT02'
  243.                                     icon = icon_deselect_all
  244.                                     text = 'Des-Visar'
  245.                                     quickinfo = 'Des-Visar todos'
  246.                                     disabled  = COND #( WHEN DATA_config-visu = abap_true THEN abap_true else l_modo ) )
  247.  
  248.                                   ( butn_type = 0
  249.                                     function = 'BOT99'
  250.                                     icon = icon_schedule_line
  251.                                     text = 'Plannig'
  252.                                     quickinfo = 'Vista Global'
  253.                                     disabled  = abap_false )
  254.                                    ).
  255.  
  256.       e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar
  257.                                     ( butn_type = 0
  258.                                       function = 'PHAS'
  259.                                       icon = icon_time
  260.                                       text = 'Imputar HAS'
  261.                                       quickinfo = 'Imputar HAS'
  262.                                       disabled  = abap_false ) ).
  263.  
  264.     when 3.
  265.       e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar
  266.                                     ( butn_type = 0
  267.                                       function = 'LEFT'
  268.                                       icon = ICON_COLUMN_LEFT
  269.                                       text = 'Anterior'
  270.                                       quickinfo = 'Semana Anterior'
  271.                                       disabled  = abap_false ) ).
  272.       e_object->mt_toolbar = VALUE #( BASE e_object->mt_toolbar
  273.                                     ( butn_type = 0
  274.                                       function = 'RIGHT'
  275.                                       icon = ICON_COLUMN_RIGHT
  276.                                       text = 'Posterior'
  277.                                       quickinfo = 'Semana Posterior'
  278.                                       disabled  = abap_false ) ).
  279.     endcase.
  280.  
  281.   ENDMETHOD.
  282.  
  283.   METHOD handle_user_command.
  284.     CASE e_ucomm.
  285.       WHEN 'BOT01'. " VISAR TODO
  286.         LOOP AT t_tab_01 ASSIGNING FIELD-SYMBOL(<f>) WHERE visadas IS INITIAL.
  287.           <f>-visadas = g_save = abap_true.
  288.         ENDLOOP.
  289.       WHEN 'BOT02'. " DES-VISAR TODO
  290.         LOOP AT t_tab_01 ASSIGNING <f> WHERE visadas IS NOT INITIAL.
  291.           g_save = abap_true.
  292.           <f>-visadas = abap_false.
  293.         ENDLOOP.
  294.       WHEN 'BOT99'.
  295.         PERFORM bot_vista_global.
  296.       WHEN 'COPY'. perform bot_copy.
  297.       WHEN 'COPYP'. perform bot_copy_modelo.
  298.       WHEN 'P011'. PERFORM bot_crea_param USING 'P'.
  299.       WHEN 'P012'. PERFORM bot_crea_param USING 'M'.
  300.       WHEN 'P013'. PERFORM bot_crea_param USING 'E'.
  301. *      WHEN 'P014'. PERFORM bot_crea_param USING 'S'.
  302.       WHEN 'P016'. PERFORM bot_crea_param USING 'T'.
  303.       WHEN 'P015'. my_config-obj->edit( ).
  304.       when 'PHAS'. perform bot_has.
  305.       when 'LEFT'. perform bot_week using '<'.
  306.       when 'RIGHT'. perform bot_week using '>'.
  307.       WHEN OTHERS.
  308.         IF e_ucomm CP 'ES*'.
  309.           PERFORM bot_crear_estat USING e_ucomm+2(2).
  310.         ENDIF.
  311.     ENDCASE.
  312.     grid_01->refresh_table_display( ).
  313.   ENDMETHOD.
  314.  
  315. ENDCLASS.

Include: Z_XX_I_HORAS_SEL

  1. TABLES: zxx_horas.
  2. SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME.
  3.   SELECT-OPTIONS: s_fecha  FOR zxx_horas-fecha,
  4.                   s_uname  FOR zxx_horas-uname DEFAULT sy-uname,
  5.                   s_proye  FOR zxx_horas-proyecto,
  6.                   s_codigo FOR zxx_horas-codigo,
  7.                   s_modul  FOR zxx_horas-modulo.
  8.  
  9. SELECTION-SCREEN END OF BLOCK b01.
  10.  
  11. SELECTION-SCREEN BEGIN OF BLOCK b02 WITH FRAME.
  12.  
  13.   SELECT-OPTIONS: s_asign for zxx_horas-ASIGNADO,
  14.                   s_avance for zxx_horas-AVANCE,
  15.                   s_descr  FOR zxx_horas-descr,
  16.                   s_status FOR zxx_horas-status,
  17.                   s_visa for zxx_horas-visadas no INTERVALS no-EXTENSION.
  18. SELECTION-SCREEN END OF BLOCK b02.
  19. PARAMETERS: p_visu as CHECKBOX DEFAULT ' '.
  20. PARAMETERS: p_vari type ZXX_HORAS_LTDX-VARIANT MATCHCODE OBJECT ZXX_HORAS_F4_LTDX DEFAULT '/DEFAULT'.
  21.  
  22. SELECTION-SCREEN SKIP 1.
  23. SELECTION-SCREEN COMMENT /01(40) g_vers.
  24.  
  25. SELECTION-SCREEN FUNCTION KEY 1.
  26. SELECTION-SCREEN FUNCTION KEY 2.
  27. SELECTION-SCREEN FUNCTION KEY 3.
  28. SELECTION-SCREEN FUNCTION KEY 4.
  29. SELECTION-SCREEN FUNCTION KEY 5.
  30.  
  31. MODULE pbo_XXXX OUTPUT.
  32.   case sy-dynnr.
  33.     when '0100'. PERFORM pbo_0100.
  34.     when '0200'. PERFORM pbo_0200.
  35.     when '0300'. PERFORM pbo_0300.
  36.   endcase.
  37.  
  38. ENDMODULE.
  39.  
  40. MODULE pai_XXXX INPUT.
  41.   case sy-dynnr.
  42.     when '0100'. PERFORM pai_0100.
  43.     when '0200'. PERFORM pai_0200.
  44.     when '0300'. PERFORM pai_0300.
  45.   endcase.
  46. ENDMODULE.

Include: Z_XX_I_HORAS_EVE

  1. AT SELECTION-SCREEN.
  2.   PERFORM eve_start_of_selection.
  3.  
  4. INITIALIZATION.
  5.   perform eve_initialization.
  6.  
  7. START-OF-SELECTION.
  8.   perform data_ini.
  9.   PERFORM data_load.
  10.  
  11. end-of-SELECTION.
  12.   PERFORM data_list.

Include: Z_XX_I_HORAS_FRM

  1. FORM data_list.
  2.   CALL SCREEN '0100'.
  3. ENDFORM.
  4.  
  5. FORM data_load_config.
  6.   DATA: l_valor(120).
  7. *    TRY. DATA(l_datum) = CONV datum( t_tab[ var_u = 'DATUM' ]-val ). CATCH cx_root. CLEAR sy-subrc. ENDTRY.
  8.  
  9.   data_config-obj = NEW zini_cl_config_files( p_ini_name = 'ZXX_HORAS.CONFIG' ).
  10.   DATA(t_tab) = CONV zini_cl_config_files=>TY_valores( data_config-obj->get_data_all( ) ).
  11.   LOOP AT t_tab INTO DATA(l_data).
  12.  
  13.     CASE l_data-var_u.
  14.       WHEN 'SUPERUSER'.
  15.         data_config-su = VALUE #( BASE data_config-su ( sign = if_fsbp_const_range=>sign_include
  16.                                                         option = if_fsbp_const_range=>option_equal
  17.                                                         low    = l_data-val ) ) .
  18.       WHEN 'ESTAT'.
  19.         SPLIT l_data-val AT ';' INTO DATA(l_001) DATA(l_002) DATA(l_003) DATA(l_044).
  20.         data_config-estat = VALUE #( BASE data_config-estat ( codigo = l_001 icono = l_002 color = l_003 texto = l_044 ) ).
  21.  
  22.       WHEN 'FESTIVOS_MMDD'.
  23.         SPLIT l_data-val AT ';' INTO TABLE DATA(T_ax).
  24.         LOOP AT t_ax INTO DATA(ax).
  25.           CHECK ax IS NOT INITIAL.
  26.           data_config-t_fest = VALUE #( BASE data_config-t_Fest ( sign   = if_fsbp_const_range=>sign_include
  27.                                                                   option = if_fsbp_const_range=>option_equal
  28.                                                                   low    = ax ) ).
  29.         ENDLOOP.
  30.  
  31.       WHEN 'FESTIVOS_AAAAMMDD'.
  32.         SPLIT l_data-val AT ';' INTO TABLE DATA(T_bx).
  33.         LOOP AT t_bx INTO DATA(bx).
  34.           CHECK bx IS NOT INITIAL.
  35.           data_config-t_festfull = VALUE #( BASE data_config-t_Festfull ( sign   = if_fsbp_const_range=>sign_include
  36.                                                                           option = if_fsbp_const_range=>option_equal
  37.                                                                           low    = bx ) ).
  38.         ENDLOOP.
  39.  
  40.       WHEN 'DEFAULT'.
  41.         SPLIT l_data-val AT ' ' INTO DATA(l_004) l_valor.
  42.         l_valor = to_upper( val = l_valor ).
  43.         IF l_valor CP 'SYST-*' OR l_valor CP 'SY-*'.
  44.           ASSIGN (l_valor) TO FIELD-SYMBOL(<ff>).
  45.           IF sy-subrc EQ 0.
  46.             l_valor = <ff>.
  47.           ENDIF.
  48.         ENDIF.
  49.         data_config-def = VALUE #( BASE data_config-def ( field = l_004 valor = l_valor ) ).
  50.  
  51.     ENDCASE.
  52.  
  53.   ENDLOOP.
  54.  
  55.   TRY. data_config-Days_Before = CONV #( t_tab[ var_u = 'DAYS_BEFORE' ]-val ). CATCH cx_root. CLEAR sy-subrc. ENDTRY.
  56.   TRY. data_config-url = CONV #( t_tab[ var_u = 'HAS_URL' ]-val ). CATCH cx_root. CLEAR sy-subrc. ENDTRY.
  57.   TRY. data_config-jira_url = CONV #( t_tab[ var_u = 'JIRA_URL' ]-val ). CATCH cx_root. CLEAR sy-subrc. ENDTRY.
  58.  
  59.   data_config-date_before = sy-datum - data_config-Days_Before.
  60.  
  61. ENDFORM.
  62.  
  63. FORM eve_initialization.
  64.   PERFORM data_load_config.
  65.  
  66.   DATA: l_num TYPE p.
  67.   sscrfields-functxt_01 = |@7Q@ Fast Track|.
  68.   g_vers = c_vers.
  69.   s_fecha = 'IBT'.
  70.   l_num = sy-datum MOD 7. "sy-datum MOD 7.
  71.   IF l_num > 1.
  72.     l_num -= 1.
  73.   ELSE.
  74.     l_num += 6.
  75.   ENDIF.
  76.   l_num -= 1.
  77.   s_fecha-low = sy-datum - l_num.
  78.   s_fecha-high = s_fecha-low + 6.
  79.   APPEND s_fecha.
  80.  
  81. ENDFORM.
  82.  
  83. FORM eve_start_of_selection.
  84.   CASE sscrfields-ucomm.
  85.     WHEN 'FC01'. PERFORM bot_fast_track.
  86.   ENDCASE.
  87. ENDFORM.
  88.  
  89. FORM bot_fast_track.
  90.   DATA: t_fields TYPE STANDARD TABLE OF sval,
  91.         l_ans    TYPE c LENGTH 1.
  92.   t_fields = VALUE #(
  93.                       ( tabname = 'ZXX_HORAS' fieldname = 'FECHA'       field_obl = abap_true  value = sy-datum )
  94.                       ( tabname = 'ZXX_HORAS' fieldname = 'UNAME'       field_obl = abap_true  value = sy-uname field_attr = '03' )
  95.                       ( tabname = 'ZXX_HORAS' fieldname = 'HORAS'       field_obl = abap_true )
  96.                       ( tabname = 'ZXX_HORAS' fieldname = 'PROYECTO'    field_obl = abap_true )
  97.                       ( tabname = 'ZXX_HORAS' fieldname = 'TIPO'      field_obl = abap_true )
  98.                       ( tabname = 'ZXX_HORAS' fieldname = 'MODULO'      field_obl = abap_true )
  99.                       ( tabname = 'ZXX_HORAS' fieldname = 'CODIGO'      field_obl = abap_true )
  100.                       ( tabname = 'ZXX_HORAS' fieldname = 'DESC_CODIGO' field_obl = abap_false )
  101.                       ( tabname = 'ZXX_HORAS' fieldname = 'ASIGNADO'    field_obl = abap_false )
  102.                       ( tabname = 'ZXX_HORAS' fieldname = 'ASIGNADO_L'  field_obl = abap_false )
  103. *                        ( tabname = 'ZXX_HORAS' fieldname = 'BEGDATE'     field_obl = abap_false )
  104. *                        ( tabname = 'ZXX_HORAS' fieldname = 'ENDDATE'     field_obl = abap_false )
  105.                       ( tabname = 'ZXX_HORAS' fieldname = 'CALLME'      field_obl = abap_false )
  106. *                      ( tabname = 'ZXX_HORAS' fieldname = 'STATUS'      field_obl = abap_true )
  107. *                      ( tabname = 'ZXX_HORAS' fieldname = 'AVANCE'      field_obl = abap_true )
  108.                       ( tabname = 'ZXX_HORAS' fieldname = 'DESCR'       field_obl = abap_false )
  109.                     ).
  110.  
  111. *--[ Cargamos los datos por defecto...
  112.   LOOP AT data_config-def INTO DATA(l_def).
  113.     TRY.
  114.         t_fields[ fieldname = l_def-field ]-value = l_def-valor.
  115.       CATCH cx_root.
  116.         CLEAR sy-subrc.
  117.     ENDTRY.
  118.   ENDLOOP.
  119.  
  120.   CALL FUNCTION 'POPUP_GET_VALUES'
  121.     EXPORTING
  122. *     NO_VALUE_CHECK  = ' '
  123.       popup_title     = 'Fast Track'
  124.       start_column    = '50'
  125.       start_row       = '5'
  126.     IMPORTING
  127.       returncode      = l_ans
  128.     TABLES
  129.       fields          = t_fields
  130.     EXCEPTIONS
  131.       error_in_fields = 1
  132.       OTHERS          = 2.
  133.   IF sy-subrc EQ 0 AND l_ans IS INITIAL.
  134.     DATA(l_fecha) = CONV datum( t_fields[ fieldname = 'FECHA' ]-value ).
  135.     SELECT MAX( indice ) FROM zxx_horas INTO @DATA(l_max)
  136.          WHERE fecha = @l_fecha AND uname = @sy-uname.
  137.  
  138.     ADD 1 TO l_max.
  139.  
  140.     DATA(to_save) = VALUE zxx_horas(
  141.     fecha = l_fecha
  142.     uname = sy-uname
  143.     indice = l_max
  144.     proyecto     = t_fields[ fieldname = 'PROYECTO' ]-value
  145.     modulo       = t_fields[ fieldname = 'MODULO' ]-value
  146.     tipo       = t_fields[ fieldname = 'TIPO' ]-value
  147.     codigo       = t_fields[ fieldname = 'CODIGO' ]-value
  148.     desc_codigo  = t_fields[ fieldname = 'DESC_CODIGO' ]-value
  149.     asignado     = t_fields[ fieldname = 'ASIGNADO' ]-value
  150.     asignado_l   = t_fields[ fieldname = 'ASIGNADO_L' ]-value
  151.     callme       = t_fields[ fieldname = 'CALLME' ]-value
  152.     BEGTIME      = sy-uzeit - ( CONV zxx_de_horas( t_fields[ fieldname = 'HORAS' ]-value ) * 3600 )
  153.     endtime      = sy-uzeit
  154.     begdate      = l_fecha
  155.     enddate      = l_fecha
  156.     horas        = CONV zxx_de_horas( t_fields[ fieldname = 'HORAS' ]-value )
  157.     status       = '40' "En pruebas
  158.     avance       = '90'
  159. *    status       = t_fields[ fieldname = 'STATUS' ]-value
  160. *    avance       = t_fields[ fieldname = 'AVANCE' ]-value
  161.     descr        = t_fields[ fieldname = 'DESCR' ]-value
  162.     ).
  163.     IF sy-uname IN data_config-su.
  164.     ELSE.
  165.       IF l_fecha < data_config-date_before.
  166.         MESSAGE s398(00) WITH 'Fecha no permitida'.
  167.         EXIT.
  168.       ENDIF.
  169.     ENDIF.
  170.     INSERT zxx_horas FROM to_save.
  171.     MESSAGE s398(00) WITH 'Datos almacenados correctamente'.
  172.   ENDIF.
  173. ENDFORM.
  174.  
  175. FORM data_ini.
  176.   data_config-visu = p_visu.
  177. ENDFORM.
  178.  
  179. FORM data_load.
  180.   REFRESH t_tab_01.
  181.  
  182.   SELECT * FROM zxx_horas INTO CORRESPONDING FIELDS OF TABLE t_tab_01
  183.     WHERE fecha    IN s_FECHA
  184.       AND uname    IN s_UNAME
  185.       AND visadas  IN s_visa
  186.       AND proyecto IN s_PROYE
  187.       AND modulo   IN s_MODUL
  188.       and ASIGNADO in s_asign
  189.       AND descr    IN s_DESCR
  190.       AND codigo   IN s_codigo
  191.       AND status   IN s_status
  192.       AND avance   IN s_avance.
  193.  
  194.   SORT t_tab_01 BY fecha uname indice.
  195.  
  196. *--[ Creamos el FCAT de la tabla
  197. *--[ Esto iría en el PBO, pero lo necesito antes
  198.   cl_salv_table=>factory( IMPORTING r_salv_table = DATA(l_alv) CHANGING t_table = t_tab_01 ).
  199.   t_fcat_01 = cl_salv_controller_metadata=>get_lvc_fieldcatalog(
  200.         r_columns      = l_alv->get_columns( )
  201.         r_aggregations  = l_alv->get_aggregations( ) ).
  202.  
  203.   SELECT domvalue_l AS valor,
  204.          ddtext     AS txt
  205.     FROM dd07t
  206.     INTO TABLE @DATA(T_keys)
  207.     WHERE ( domname    = 'ZXX_D_PROYECTO' OR
  208.             domname    = 'ZXX_D_STATUS' OR
  209.             domname    = 'ZXX_D_TIPO' OR
  210.             domname    = 'ZXX_D_MODULO' )
  211.       AND ddlanguage = @sy-langu AND
  212.           as4local = 'A' AND
  213.           as4vers  = '0000'
  214.     ORDER BY domname, valpos.
  215.  
  216.   SELECT f~bname, p~name_first && ' ' && p~name_last AS nombre
  217.       INTO TABLE @DATA(T_lusers)
  218.       FROM usr21 AS f INNER JOIN adrp AS p ON f~persnumber = p~persnumber
  219.     WHERE f~bname  = @sy-uname.
  220.  
  221. *  DATA(l_datum) = CONV sydatum( sy-datum - c_proteccion ).
  222.   DATA: t_rw TYPE lvc_t_styl,
  223.         t_r  TYPE lvc_t_styl.
  224.  
  225.   PERFORM data_fill_edit USING cl_gui_alv_grid=>mc_style_disabled CHANGING t_r.
  226.   PERFORM data_fill_edit USING cl_gui_alv_grid=>mc_style_enabled  CHANGING t_rw.
  227.  
  228.   LOOP AT t_tab_01 ASSIGNING FIELD-SYMBOL(<f>).
  229.     AT FIRST.
  230. *--[ Protegemos los textos
  231. *      DATA: t_cell_read TYPE lvc_t_styl.
  232. *      REFRESH t_cell_REad.
  233. *      sort t_fcat_01 by FIELDNAME ASCENDING.
  234. *      LOOP AT t_fcat_01 INTO DATA(l_f) WHERE fieldname CP '*_TXT' .
  235. *        t_cell_read = VALUE #( BASE t_cell_read ( fieldname = l_f-fieldname style = cl_gui_alv_grid=>mc_style_disabled ) ).
  236. *      ENDLOOP.
  237. *      SORT t_fcat_01.
  238.       SELECT wotnr, langt FROM t246 INTO TABLE @DATA(t246) WHERE sprsl = @sy-langu ORDER BY wotnr.
  239.     ENDAT.
  240.     DATA(l_tabix) = sy-tabix.
  241. *--[ Esto se puede optimizar, luego, ahora tengo prisa
  242.     TRY.
  243.         <f>-uname_txt = t_lusers[ bname = <f>-uname ]-nombre.
  244.       CATCH cx_root.
  245.         SELECT f~bname, p~name_first && ' ' && p~name_last AS nombre
  246.                APPENDING CORRESPONDING FIELDS OF TABLE @T_lusers
  247.                FROM usr21 AS f INNER JOIN adrp AS p ON f~persnumber = p~persnumber
  248.                WHERE f~bname  = @<f>-uname.
  249.         IF sy-subrc EQ 0.
  250.           <f>-uname_txt = t_lusers[ bname = <f>-uname ]-nombre.
  251.         ENDIF.
  252.     ENDTRY.
  253.  
  254.     IF <f>-asignado IS NOT INITIAL.
  255.       TRY.
  256.           <f>-asignado_txt = t_lusers[ bname = <f>-asignado ]-nombre.
  257.         CATCH cx_root.
  258.           SELECT f~bname, p~name_first && ' ' && p~name_last AS nombre
  259.                  APPENDING CORRESPONDING FIELDS OF TABLE @T_lusers
  260.                  FROM usr21 AS f INNER JOIN adrp AS p ON f~persnumber = p~persnumber
  261.                  WHERE f~bname  = @<f>-asignado.
  262.           IF sy-subrc EQ 0.
  263.             <f>-asignado_txt = t_lusers[ bname = <f>-asignado ]-nombre.
  264.           ENDIF.
  265.       ENDTRY.
  266.     ENDIF.
  267.  
  268.     IF <f>-modulo IS NOT INITIAL.
  269.       TRY.
  270.           <f>-modulo_txt = t_keys[ valor = <f>-modulo ]-txt.
  271.         CATCH cx_root.
  272.           CLEAR sy-subrc.
  273.       ENDTRY.
  274.     ENDIF.
  275.     IF <f>-fecha IS NOT INITIAL.
  276.       DATA: l_dia TYPE scal-indicator.
  277.       CALL FUNCTION 'DATE_COMPUTE_DAY'
  278.         EXPORTING
  279.           date = <f>-fecha
  280.         IMPORTING
  281.           day  = l_dia.
  282.       TRY.
  283.           <f>-fecha_txt = t246[ l_dia ]-langt.
  284.         CATCH cx_root.
  285.           CLEAR sy-subrc.
  286.       ENDTRY.
  287.  
  288.     ENDIF.
  289. *    IF <f>-tipo IS NOT INITIAL.
  290.     TRY.
  291.         <f>-tipo_txt = t_keys[ valor = <f>-tipo ]-txt.
  292.       CATCH cx_root.
  293.         CLEAR sy-subrc.
  294.     ENDTRY.
  295. *    ENDIF.
  296.  
  297.     IF <f>-proyecto IS NOT INITIAL.
  298.       TRY.
  299.           <f>-proyecto_txt = t_keys[ valor = <f>-proyecto ]-txt.
  300.         CATCH cx_root.
  301.           CLEAR sy-subrc.
  302.       ENDTRY.
  303.     ENDIF.
  304.  
  305.     IF <f>-status IS NOT INITIAL.
  306.       TRY.
  307.           <f>-status_txt = t_keys[ valor = <f>-status ]-txt.
  308.         CATCH cx_root.
  309.           CLEAR sy-subrc.
  310.       ENDTRY.
  311.     ENDIF.
  312.  
  313.  
  314.     IF sy-uname IN data_config-su.
  315.       TRY. <f>-celltab = VALUE #( BASE <f>-celltab ( fieldname = 'VISADAS' style = cl_gui_alv_grid=>mc_style_enabled ) ).CATCH cx_root. ENDTRY.
  316.     ELSE.
  317.       TRY. <f>-celltab = COND #( WHEN <f>-fecha < data_config-date_before THEN t_r ELSE t_rw ). CATCH cx_root. ENDTRY.
  318.       TRY. <f>-celltab = COND #( WHEN sy-uname NE <f>-uname THEN t_r ELSE <f>-celltab ). CATCH cx_root. ENDTRY.
  319.       TRY. <f>-celltab = VALUE #( BASE <f>-celltab ( fieldname = 'VISADAS' style = cl_gui_alv_grid=>mc_style_disabled ) ). CATCH cx_root. ENDTRY.
  320.     ENDIF.
  321. *--[ Bloqueamos los registros *_TXT
  322. *--[ Protegemos los textos
  323.     TRY. <f>-celltab = VALUE #( BASE <f>-celltab ( fieldname = 'FECHA'        style = cl_gui_alv_grid=>mc_style_disabled ) ). CATCH cx_root. ENDTRY.
  324.     TRY. <f>-celltab = VALUE #( BASE <f>-celltab ( fieldname = 'UNAME'        style = cl_gui_alv_grid=>mc_style_disabled ) ). CATCH cx_root. ENDTRY.
  325.     TRY. <f>-celltab = VALUE #( BASE <f>-celltab ( fieldname = 'UNAME_TXT'    style = cl_gui_alv_grid=>mc_style_disabled ) ). CATCH cx_root. ENDTRY.
  326.     TRY. <f>-celltab = VALUE #( BASE <f>-celltab ( fieldname = 'PROYECTO_TXT' style = cl_gui_alv_grid=>mc_style_disabled ) ). CATCH cx_root. ENDTRY.
  327.     TRY. <f>-celltab = VALUE #( BASE <f>-celltab ( fieldname = 'ASIGNADO_TXT' style = cl_gui_alv_grid=>mc_style_disabled ) ). CATCH cx_root. ENDTRY.
  328.     TRY. <f>-celltab = VALUE #( BASE <f>-celltab ( fieldname = 'STATUS_TXT'   style = cl_gui_alv_grid=>mc_style_disabled ) ). CATCH cx_root. ENDTRY.
  329.     TRY. <f>-celltab = VALUE #( BASE <f>-celltab ( fieldname = 'MODULO_TXT'   style = cl_gui_alv_grid=>mc_style_disabled ) ). CATCH cx_root. ENDTRY.
  330.  
  331.   ENDLOOP.
  332.  
  333.   PERFORM data_load_lock.
  334.  
  335. ENDFORM.
  336.  
  337. FORM data_load_lock.
  338.  
  339.   DATA: t_rw TYPE lvc_t_styl,
  340.         t_r  TYPE lvc_t_styl.
  341.  
  342. *--[ Todo Bloqueado
  343.   LOOP AT t_fcat_01 ASSIGNING FIELD-SYMBOL(<ff>).
  344.     t_r = VALUE #( BASE t_r ( fieldname = <ff>-fieldname       style = cl_gui_alv_grid=>mc_style_disabled ) ).
  345.   ENDLOOP.
  346.  
  347.   LOOP AT t_tab_01 ASSIGNING FIELD-SYMBOL(<f>).
  348.  
  349.     IF p_visu = abap_true.
  350.       TRY. <f>-celltab[] = t_R[]. CATCH cx_root. ENDTRY.
  351.       CONTINUE. "<-- No bloqueamos
  352.     ENDIF.
  353.     CALL FUNCTION 'ENQUEUE_EZXX_HORAS'
  354.       EXPORTING
  355.         mode_zxx_horas = 'E'
  356.         mandt          = sy-mandt
  357.         fecha          = <f>-fecha
  358.         uname          = <f>-uname
  359.         indice         = <f>-indice
  360. *       X_FECHA        = ' '
  361. *       X_UNAME        = ' '
  362. *       X_INDICE       = ' '
  363. *       _SCOPE         = '2'
  364. *       _WAIT          = ' '
  365. *       _COLLECT       = ' '
  366.       EXCEPTIONS
  367.         foreign_lock   = 1
  368.         system_failure = 2
  369.         OTHERS         = 3.
  370.  
  371.     IF sy-subrc <> 0.
  372.       TRY. <f>-celltab[] = t_R[]. CATCH cx_root. ENDTRY.
  373.       MESSAGE s398(00) WITH 'Existen registros bloqueados por ' sy-msgv1 '' ''.
  374.     ENDIF.
  375.   ENDLOOP.
  376. ENDFORM.
  377.  
  378. FORM data_fill_edit USING p_modo CHANGING t_tab TYPE lvc_t_styl.
  379.   TRY.
  380.       t_tab = VALUE #( ( fieldname = 'FECHA'       style = p_modo )
  381.                        ( fieldname = 'UNAME'       style = p_modo )
  382.                        ( fieldname = 'INDICE'      style = p_modo )
  383.                        ( fieldname = 'PROYECTO'    style = p_modo )
  384.                        ( fieldname = 'MODULO'      style = p_modo )
  385.                        ( fieldname = 'TIPO'        style = p_modo )
  386.                        ( fieldname = 'CODIGO'      style = p_modo )
  387.                        ( fieldname = 'DESC_CODIGO' style = p_modo )
  388.                        ( fieldname = 'ASIGNADO'    style = p_modo )
  389.                        ( fieldname = 'ASIGNADO_L'  style = p_modo )
  390.                        ( fieldname = 'BEGDATE'     style = p_modo )
  391.                        ( fieldname = 'ENDDATE'     style = p_modo )
  392.                        ( fieldname = 'CALLME'      style = p_modo )
  393.                        ( fieldname = 'HORAS'       style = p_modo )
  394.                        ( fieldname = 'STATUS'      style = p_modo )
  395.                        ( fieldname = 'AVANCE'      style = p_modo )
  396.                        ( fieldname = 'DESCR'       style = p_modo )
  397.                      ).
  398.     CATCH cx_root.
  399.   ENDTRY.
  400. ENDFORM.
  401.  
  402.  
  403. FORM pbo_0300.
  404.   SET PF-STATUS 'MAIN0100' EXCLUDING t_fcode.
  405.   SET TITLEBAR 'TIT01' WITH 'Imputar Horas'.
  406.  
  407.   CHECK cc_03 IS INITIAL.
  408.   cc_03 = NEW  cl_gui_custom_container( container_name = 'CC_ALV_03' ).
  409.   DATA(G_SPlIT)   = NEW cl_gui_splitter_container( parent = cc_03
  410.                                                    rows = 2
  411.                                                    columns = 1 ).
  412.   grid_03 = NEW cl_gui_alv_grid( i_parent = G_SPlIT->get_container( row = 1 column = 1 ) ).
  413.  
  414.   g_split->set_row_height( id = 1 height = 30  ).
  415.   DATA(g_html_control) = NEW cl_gui_html_viewer( parent = G_SPlIT->get_container( row = 2 column = 1 ) ).
  416.  
  417.  
  418.   g_html_control->show_data( EXPORTING url = data_config-url ).
  419.  
  420.   cl_salv_table=>factory( IMPORTING r_salv_table = DATA(l_alv) CHANGING t_table = t_tab_has ).
  421.   t_fcat_03 = cl_salv_controller_metadata=>get_lvc_fieldcatalog(
  422.         r_columns      = l_alv->get_columns( )
  423.         r_aggregations  = l_alv->get_aggregations( ) ).
  424.   SELECT wotnr, langt FROM t246 INTO TABLE @DATA(t246) WHERE sprsl = @sy-langu ORDER BY wotnr.
  425.   LOOP AT t_fcat_03 ASSIGNING FIELD-SYMBOL(<dx>).
  426.     CASE <dx>-fieldname.
  427.       WHEN 'PROYECTO'.
  428.         <dx>-scrtext_s = <dx>-scrtext_m = <dx>-coltext   = <dx>-seltext =  <dx>-scrtext_l = 'Proyecto / Estadistico'.
  429.     ENDCASE.
  430.     IF <dx>-fieldname CP 'COL_*'.
  431.       <dx>-scrtext_s = <dx>-scrtext_m = <dx>-coltext = <dx>-seltext = <dx>-scrtext_l = t246[ wotnr = <dx>-fieldname+5(1) ]-langt.
  432.       <dx>-do_sum = abap_true.
  433.     ENDIF.
  434.   ENDLOOP.
  435.  
  436.   G_event_has = NEW lcl_event_handler( ).
  437.  
  438.   G_event_has->my_config = data_config.
  439.   G_event_has->my_config-alv = 3.
  440.  
  441.   SET HANDLER G_event_has->handle_toolbar      FOR grid_03.
  442.   SET HANDLER G_event_has->handle_user_command FOR grid_03.
  443.   SET HANDLER G_event_01->handle_data_changed  FOR grid_03.
  444.   SET HANDLER G_event_01->handle_menu_button   FOR grid_03.
  445.  
  446.   grid_03->set_toolbar_interactive( ).
  447.  
  448.   grid_03->set_table_for_first_display(
  449.     EXPORTING
  450.       is_variant           = gs_variant_02
  451.       is_layout            = gs_layout_02
  452.       i_save               = 'A'
  453.       it_toolbar_excluding = gt_toolbar_has
  454.     CHANGING
  455.       it_fieldcatalog      = t_fcat_03 "gt_field
  456.       it_outtab            = t_tab_has ).
  457. ENDFORM.
  458.  
  459. FORM pbo_0200.
  460.  
  461.   SET PF-STATUS 'POPUP0200' EXCLUDING t_fcode.
  462.   SET TITLEBAR 'TIT01' WITH ''.
  463.  
  464.   CHECK grid_02 IS INITIAL.
  465.  
  466.   gs_layout_02-cwidth_opt = 'X'.
  467. *    gs_layout-sel_mode = 'A'.
  468.   gs_layout_02-zebra = abap_true.
  469. *    gs_layout-stylefname = 'CELLTAB'.
  470.   gs_layout_02-ctab_fname = 'CELLCOLOR'.
  471. *    gs_variant-report = sy-repid.
  472.  
  473. *  cc_02 = NEW cl_gui_custom_container( cm_02 ).
  474.   grid_02 = NEW cl_gui_alv_grid( cl_gui_container=>default_screen ).
  475.  
  476. *--[ Creamos el FCAT de la tabla interna
  477.   cl_salv_table=>factory( IMPORTING r_salv_table = DATA(l_alv) CHANGING t_table = t_tab_03 ).
  478.   t_fcat_02 = cl_salv_controller_metadata=>get_lvc_fieldcatalog(
  479.         r_columns      = l_alv->get_columns( )
  480.         r_aggregations  = l_alv->get_aggregations( ) ).
  481.  
  482.   LOOP AT t_fcat_02 ASSIGNING FIELD-SYMBOL(<f>).
  483.     <f>-col_pos = sy-tabix.
  484.     CASE <f>-fieldname.
  485.       WHEN 'MES'.
  486. *        <f>-do_sum = abap_true.
  487.         <f>-FIX_COLUMn = abap_true.
  488.         <f>-scrtext_s =
  489.         <f>-scrtext_m =
  490.         <f>-coltext   = <f>-seltext =
  491.         <f>-scrtext_l = TEXT-c05.
  492.       WHEN 'UNAME'.
  493. *        <f>-do_sum = abap_true.
  494.         <f>-FIX_COLUMn = abap_true.
  495.         <f>-scrtext_s =
  496.         <f>-scrtext_m =
  497.         <f>-coltext   = <f>-seltext =
  498.         <f>-scrtext_l = TEXT-c06.
  499.       WHEN 'GJAHR'.
  500. *        <f>-do_sum = abap_true.
  501.         <f>-FIX_COLUMn = abap_true.
  502.         <f>-scrtext_s =
  503.         <f>-scrtext_m =
  504.         <f>-coltext   = <f>-seltext =
  505.         <f>-scrtext_l = TEXT-c07.
  506.  
  507.       WHEN 'TOTAL'.
  508. *        <f>-do_sum = abap_true.
  509.         <f>-FIX_COLUMn = abap_true.
  510.         <f>-scrtext_s =
  511.         <f>-scrtext_m =
  512.         <f>-coltext   = <f>-seltext =
  513.         <f>-scrtext_l = TEXT-c08.
  514.     ENDCASE.
  515.  
  516.     IF <f>-fieldname CP 'DIA_*'.
  517.       <f>-scrtext_s =
  518.       <f>-scrtext_m =
  519.       <f>-coltext   = <f>-seltext =
  520.       <f>-scrtext_l = <f>-fieldname+4(2).
  521.       <f>-icon = abap_true.
  522.     ENDIF.
  523.  
  524.   ENDLOOP.
  525.  
  526.   t_sort_02 = VALUE #( ( fieldname = 'GJAHR' up = abap_true subtot = abap_true )
  527.                        ( fieldname = 'MES'   up = abap_true subtot = abap_true )
  528.                        ( fieldname = 'UNAME' up = abap_true subtot = abap_true ) ).
  529.  
  530. *    PERFORM alv_remove_buttons.
  531.   grid_02->set_table_for_first_display(
  532.     EXPORTING
  533.       is_variant           = gs_variant_02
  534.       is_layout            = gs_layout_02
  535.       i_save               = 'A'
  536.       it_toolbar_excluding = gt_toolbar
  537.     CHANGING
  538.       it_fieldcatalog      = t_fcat_02 "gt_field
  539.       it_sort              = t_sort_02
  540.       it_outtab            = t_tab_03 ).
  541.  
  542. ENDFORM.
  543.  
  544. FORM pbo_0100.
  545.   IF sy-tcode = 'SE38'.
  546.     REFRESH t_fcode.
  547.   ELSE.
  548.   ENDIF.
  549.   IF p_visu = abap_true. APPEND 'SAVE' TO t_fcode. ENDIF.
  550.   SET PF-STATUS 'MAIN0100' EXCLUDING t_fcode.
  551.   SET TITLEBAR 'TIT01' WITH ''.
  552.  
  553.   CHECK grid_01 IS INITIAL.
  554.  
  555.   gs_layout-cwidth_opt = 'X'.
  556.   gs_layout-sel_mode = 'A'.
  557.   gs_layout-zebra = abap_true.
  558.   gs_layout-stylefname = 'CELLTAB'.
  559.   gs_variant-report = sy-repid.
  560.   gs_variant-variant = p_vari.
  561.  
  562.   cc_01 = NEW cl_gui_custom_container( 'CC_ALV_01' ).
  563.   grid_01 = NEW cl_gui_alv_grid( cc_01 ). "cl_gui_container=>default_screen ).
  564.  
  565.   DATA(t_fcat_02) = t_fcat_01.
  566.   REFRESH t_fcat_02.
  567.   LOOP AT t_fcat_01 ASSIGNING FIELD-SYMBOL(<f>) WHERE fieldname NP '*_TXT'.
  568.     APPEND <f> TO t_fcat_02.
  569.     READ TABLE t_fcat_01 ASSIGNING FIELD-SYMBOL(<ff>) WITH KEY fieldname = |{ <f>-fieldname }_TXT|. "l_name.
  570.     CHECK sy-subrc EQ 0.
  571.     APPEND <ff> TO t_fcat_02.
  572.   ENDLOOP.
  573.   t_fcat_01[] = t_fcat_02[].
  574.   LOOP AT t_fcat_01 ASSIGNING <f>.
  575.     <f>-col_pos = sy-tabix.
  576.     <f>-edit = abap_true.
  577.  
  578.     IF <f>-fieldname CP '*TXT'.
  579.       <f>-scrtext_s =
  580.       <f>-scrtext_m =
  581.       <f>-coltext   = <f>-seltext =
  582.       <f>-scrtext_l = TEXT-c02.
  583.       <f>-edit = abap_false.
  584.     ENDIF.
  585.  
  586.     CASE <f>-fieldname.
  587.       WHEN 'FECHA' OR 'UNAME'.
  588.         <f>-fix_column = abap_True.
  589.       WHEN 'NAME'.
  590.         <f>-scrtext_s =
  591.         <f>-scrtext_m =
  592.         <f>-coltext   = <f>-seltext =
  593.         <f>-scrtext_l = TEXT-c01.
  594.         <f>-outputlen = 100.
  595.       WHEN 'INDICE'.
  596.         <f>-no_out = abap_true.
  597.       WHEN 'CALLME' OR 'VISADAS'.
  598.         <f>-checkbox = abap_true.
  599.       when 'CODIGO'.
  600.         <f>-hotspot = abap_true.
  601.       WHEN 'HORAS'.
  602.         <f>-do_sum = abap_true.
  603.       WHEN 'MANDT'. <f>-no_out = <f>-tech = abap_true.
  604.       WHEN 'FECHA_TXT'.
  605.         <f>-fix_column = abap_True.
  606.         <f>-coltext   = <f>-seltext = <f>-scrtext_l = TEXT-c09.
  607.     ENDCASE.
  608.  
  609.   ENDLOOP.
  610.  
  611.   t_sort = VALUE #( ( SPOS = 1 fieldname = 'FECHA'    up = abap_true subtot = abap_true )
  612.                     ( SPOS = 2 fieldname = 'UNAME'    up = abap_true subtot = abap_true )
  613.                     ( SPOS = 3 fieldname = 'BEGTI'    up = abap_true )
  614.                     ( SPOS = 4 fieldname = 'INDICE'   up = abap_true )
  615.                     ( SPOS = 5 fieldname = 'PROYECTO' up = abap_true ) ).
  616.  
  617.   PERFORM alv_remove_buttons.
  618.   grid_01->set_table_for_first_display(
  619.     EXPORTING
  620.       is_variant           = gs_variant
  621.       is_layout            = gs_layout
  622.       i_save               = 'A'
  623.       it_toolbar_excluding = gt_toolbar
  624.     CHANGING
  625.       it_fieldcatalog      = t_fcat_01 "gt_field
  626.       it_sort              = t_sort
  627.       it_outtab            = t_tab_01 ).
  628.  
  629.   G_event_01 = NEW lcl_event_handler( ).
  630.  
  631.   G_event_01->my_config = data_config.
  632.  
  633.   G_event_01->my_config-alv = 1.
  634.  
  635.   SET HANDLER G_event_01->handle_toolbar      FOR grid_01.
  636.   SET HANDLER G_event_01->handle_user_command FOR grid_01.
  637.   SET HANDLER G_event_01->handle_data_changed FOR grid_01.
  638.   SET HANDLER G_event_01->handle_menu_button  FOR grid_01.
  639.   SET HANDLER G_event_01->handle_hotspot      FOR grid_01.
  640.  
  641.   grid_01->set_toolbar_interactive( ).
  642.  
  643.   grid_01->register_edit_event( EXPORTING i_event_id = cl_gui_alv_grid=>mc_evt_modified ).
  644.   grid_01->register_edit_event( EXPORTING i_event_id = cl_gui_alv_grid=>mc_evt_enter ).
  645.  
  646. ENDFORM.
  647.  
  648. FORM alv_remove_buttons.
  649.   CLEAR gt_toolbar.
  650.   gt_toolbar = VALUE #( BASE gt_toolbar ( cl_gui_alv_grid=>mc_fc_detail  )
  651.                                         ( cl_gui_alv_grid=>mc_fc_loc_copy )
  652.                                         ( cl_gui_alv_grid=>mc_fc_loc_paste  )
  653.                                         ( cl_gui_alv_grid=>mc_fc_loc_copy_row )
  654.                                         ( cl_gui_alv_grid=>mc_fc_loc_paste_new_row )
  655.                                         ( cl_gui_alv_grid=>mc_fc_loc_cut  )
  656.                                         ( cl_gui_alv_grid=>mc_fc_loc_undo  )
  657.                                         ( cl_gui_alv_grid=>mc_fc_check   )
  658.                                         ( cl_gui_alv_grid=>mc_fc_refresh )
  659.                                         ( cl_gui_alv_grid=>mc_fc_info )
  660.                                         ( cl_gui_alv_grid=>mc_fc_html )
  661.                                         ( cl_gui_alv_grid=>mc_fc_help )
  662.                       ).
  663.   IF p_visu = abap_true.
  664.     gt_toolbar = VALUE #( BASE gt_toolbar ( cl_gui_alv_grid=>mc_fc_loc_delete_row  )
  665.                                           ( cl_gui_alv_grid=>mc_fc_loc_insert_row )
  666.                                           ( cl_gui_alv_grid=>mc_fc_loc_append_row )
  667.                          ).
  668.   ENDIF.
  669.  
  670.   gt_toolbar_has = VALUE #( BASE gt_toolbar ( cl_gui_alv_grid=>mc_fc_detail  )
  671.                                       ( cl_gui_alv_grid=>mc_fc_loc_copy )
  672.                                       ( cl_gui_alv_grid=>mc_fc_loc_paste  )
  673.                                       ( cl_gui_alv_grid=>mc_fc_loc_paste_new_row )
  674.                                       ( cl_gui_alv_grid=>mc_fc_loc_cut  )
  675.                                       ( cl_gui_alv_grid=>mc_fc_loc_undo  )
  676.                                       ( cl_gui_alv_grid=>mc_fc_check   )
  677.                                       ( cl_gui_alv_grid=>mc_fc_refresh )
  678.                                       ( cl_gui_alv_grid=>mc_fc_info )
  679.                                       ( cl_gui_alv_grid=>mc_fc_html )
  680.                                       ( cl_gui_alv_grid=>mc_fc_help )
  681.                     ).
  682.  
  683. ENDFORM.
  684.  
  685. FORM pai_0200.
  686.   DATA(l_okcode) = g_okcode.
  687.   CLEAR g_okcode.
  688.   CASE l_okcode.
  689.     WHEN 'BACK'.
  690.       grid_02->Free( ).
  691.       CLEAR: grid_02.
  692.       LEAVE TO SCREEN 0.
  693.   ENDCASE.
  694. ENDFORM.
  695.  
  696. FORM pai_0300.
  697.   DATA(l_okcode) = g_okcode.
  698.   CLEAR g_okcode.
  699.   CASE l_okcode.
  700.     WHEN 'BACK'.
  701.       cc_03->free( ).
  702.       CLEAR: cc_03, grid_03.
  703.       LEAVE TO SCREEN 0.
  704.   ENDCASE.
  705. ENDFORM.
  706.  
  707. FORM pai_0100.
  708.   DATA(l_okcode) = g_okcode.
  709.   CLEAR g_okcode.
  710.   CASE l_okcode.
  711.     WHEN 'SAVE'.      PERFORM boton_save.
  712.     WHEN 'BACK'.      PERFORM boton_exit_program.
  713.   ENDCASE.
  714. ENDFORM.
  715.  
  716. FORM boton_save_delete.
  717.  
  718. *  DATA(l_datum) = CONV sydatum( sy-datum - c_proteccion ).
  719. *--[ Buscamos los borrados
  720.   LOOP AT t_tab_del INTO DATA(l_02).
  721.  
  722.     IF sy-uname IN data_config-su.
  723.     ELSE.
  724.       IF l_02-fecha < data_config-date_before OR
  725.          sy-uname NE l_02-uname.
  726.         APPEND l_02 TO t_tab_01. "<-- Restauramos
  727.         CONTINUE. " No se puede borrar
  728.       ENDIF.
  729.     ENDIF.
  730.  
  731. *--[ Eliminamos el registro de BD
  732.     DELETE FROM zxx_horas
  733.       WHERE fecha  = l_02-fecha
  734.         AND uname  = l_02-uname
  735.         AND indice = l_02-indice.
  736. *--[ Eliminamos las posibles actualizaciones del registro
  737.     DELETE t_tab_upd WHERE fecha  = l_02-fecha
  738.                        AND uname  = l_02-uname
  739.                        AND indice = l_02-indice.
  740.   ENDLOOP.
  741.   REFRESH t_tab_del. "<-- Reinicializamos el contador
  742. ENDFORM.
  743.  
  744. FORM boton_save_update.
  745.   DATA: l_tab TYPE zxx_horas.
  746. *  DATA(l_datum) = CONV sydatum( sy-datum - c_proteccion ).
  747.   LOOP AT t_tab_upd INTO DATA(ax).
  748.  
  749. *--[ Localizamos el registro con los cambios
  750.     READ TABLE t_tab_01 INTO DATA(bx) WITH KEY fecha  = ax-fecha
  751.                                                uname  = ax-uname
  752.                                                indice = ax-indice.
  753.  
  754.     CHECK sy-subrc EQ 0.
  755.  
  756.     IF sy-uname IN data_config-su.
  757.     ELSE.
  758.       IF bx-fecha < data_config-date_before OR
  759.          sy-uname NE bx-uname.
  760.         CONTINUE. " No se puede borrar
  761.       ENDIF.
  762.     ENDIF.
  763.  
  764. *--[ Grabamos en BD
  765.     CLEAR l_tab.
  766.     MOVE-CORRESPONDING bx TO l_tab.
  767.     MODIFY zxx_horas FROM l_tab.
  768.  
  769. *--[ Borramos los posibles repetidos
  770.     DELETE t_tab_upd WHERE fecha  = ax-fecha AND
  771.                            uname  = ax-uname AND
  772.                            indice = ax-indice.
  773.  
  774.   ENDLOOP.
  775.   REFRESH t_tab_upd.
  776. ENDFORM.
  777.  
  778. FORM boton_save_insert.
  779.   TYPES: BEGIN OF ty_tmp,
  780.            fecha  TYPE datum,
  781.            uname  TYPE xubname,
  782.            indice TYPE sytabix,
  783.          END OF ty_tmp.
  784.   DATA: t_tmp TYPE STANDARD TABLE OF ty_tmp,
  785.         l_tab TYPE zxx_horas.
  786.  
  787. *  DATA(l_datum) = CONV sydatum( sy-datum - c_proteccion ).
  788.  
  789.   LOOP AT t_tab_01 ASSIGNING FIELD-SYMBOL(<ax>) WHERE indice IS INITIAL.
  790.  
  791.     IF sy-uname IN data_config-su.
  792.     ELSE.
  793.       IF <ax>-fecha < data_config-date_before OR
  794.          sy-uname NE <ax>-uname.
  795.         CONTINUE. " No se puede insertar
  796.       ENDIF.
  797.     ENDIF.
  798.  
  799.     READ TABLE t_tmp ASSIGNING FIELD-SYMBOL(<bx>) WITH KEY fecha = <ax>-fecha
  800.                                                            uname = <ax>-uname.
  801.     IF sy-subrc EQ 0.
  802.       ADD 1 TO <bx>-indice.
  803.     ELSE.
  804.       APPEND INITIAL LINE TO t_tmp ASSIGNING <bx>.
  805.       <bx>-fecha = <ax>-fecha.
  806.       <bx>-uname = <ax>-uname.
  807.       SELECT MAX( indice ) INTO @DATA(l_indice) FROM zxx_horas WHERE fecha = @<ax>-fecha AND
  808.                                                                      uname = @<ax>-uname.
  809.       IF sy-subrc EQ 0.
  810.         <bx>-indice = l_indice + 1.
  811.       ELSE.
  812.         <bx>-indice = 1. "
  813.       ENDIF.
  814.     ENDIF.
  815.  
  816.     <ax>-indice = <bx>-indice.
  817.     CLEAR l_tab.
  818.     MOVE-CORRESPONDING <ax> TO l_tab.
  819.     MODIFY zxx_horas FROM l_tab.
  820.  
  821.   ENDLOOP.
  822. ENDFORM.
  823.  
  824. FORM boton_save.
  825.   grid_01->check_changed_data( ).
  826.  
  827. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  828. *--[ Verificamos los campos obligatorios.
  829.   DATA(l_save) = abap_true.
  830.  
  831.   LOOP AT t_tab_01 INTO DATA(l_tab) WHERE fecha >= '20241201' AND
  832.                                           codigo IS INITIAL.
  833.     CLEAR l_save.
  834.     MESSAGE s398(00) WITH TEXT-e02.
  835.     EXIT.
  836.   ENDLOOP.
  837.  
  838.   CHECK l_save = abap_true.
  839.  
  840.   CHECK g_save = abap_true.
  841.  
  842.   PERFORM boton_save_delete.
  843.   PERFORM boton_save_update.
  844.   PERFORM boton_save_insert.
  845. *--[ Recargamos para que se actualicen TODOS los registros de BD
  846. *--[ Obviamente los ajenos
  847.   PERFORM data_load.
  848.  
  849.   grid_01->refresh_table_display( ).
  850.   CLEAR g_save.
  851.   MESSAGE s398(00) WITH 'Datos grabados correctamente' '' '' ''.
  852.  
  853. ***  exit.
  854. **** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  855. ****--[ Arreglamos índices: Triple LOOP dinámica :D :D :D
  856. ****--[ A alguien le va a explotar la cabeza
  857. ***  SORT t_tab_01 BY fecha uname indice DESCENDING.
  858. ***  LOOP AT t_tab_01 ASSIGNING FIELD-SYMBOL(<f>) WHERE indice IS INITIAL.
  859. ***
  860. ***    LOOP AT t_tab_01 INTO DATA(l_f) WHERE fecha = <f>-fecha AND
  861. ***                                          uname = <f>-uname AND
  862. ***                                           NOT indice IS INITIAL.
  863. ***      data(l_num) = l_f-indice .
  864. ***      LOOP AT t_tab_01 ASSIGNING FIELD-SYMBOL(<ff>) WHERE fecha = <f>-fecha AND
  865. ***                                                          uname = <f>-uname AND
  866. ***        indice IS INITIAL.
  867. ***          <ff>-indice = l_num = l_num + 1.
  868. ***      endloop.
  869. ***
  870. ***      EXIT.
  871. ***    ENDLOOP.
  872. ***    IF <f>-indice IS INITIAL.
  873. ***      <f>-indice = 1.
  874. ***    ENDIF.
  875. ***  ENDLOOP.
  876. **** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  877. ****--[ Quitamos tabla de textos, para grabar sólo lo que toca...
  878. ***  DATA: t_tmp TYPE STANDARD TABLE OF zxx_horas,
  879. ***        l_tmp LIKE LINE OF t_tmp.
  880. ***  REFRESH t_tmp.
  881. ***  LOOP AT t_tab_01 INTO l_tab_01.
  882. ***
  883. ***    IF sy-uname IN gr_su.
  884. ***    ELSE.
  885. ***      CHECK l_tab_01-uname = sy-uname. " Sólo usuarios propios
  886. ***    ENDIF.
  887. ***
  888. ***    CLEAR l_tmp.
  889. ***    MOVE-CORRESPONDING l_tab_01 TO l_tmp.
  890. ***    APPEND l_tmp TO t_tmp.
  891. ***  ENDLOOP.
  892. ***  MODIFY zxx_horas FROM TABLE t_tmp. "t_tab_01.
  893. ***  SORT t_tab_01 BY fecha uname indice.
  894. ***  t_tab_02[] = t_tab_01[]. "<-- BackUp
  895. ***  grid_01->refresh_table_display( ).
  896. ***  CLEAR g_save.
  897. ENDFORM.
  898.  
  899. FORM boton_exit_program.
  900. *--[ Destruir controladores y ALVs
  901.   IF g_save IS NOT INITIAL.
  902.     PERFORM popup_to_save CHANGING sy-subrc.
  903.     CHECK sy-subrc EQ 0.
  904.     CLEAR g_save.
  905.   ENDIF.
  906.  
  907.   CLEAR: grid_01.
  908.   LEAVE TO SCREEN 0.
  909. ENDFORM.
  910.  
  911.  
  912. FORM popup_to_save CHANGING p_subrc TYPE sysubrc.
  913.   DATA: l_ans(1).
  914.   CALL FUNCTION 'POPUP_TO_CONFIRM'
  915.     EXPORTING
  916.       titlebar              = TEXT-t07
  917.       text_question         = TEXT-q01
  918.       text_button_1         = TEXT-q02
  919.       text_button_2         = TEXT-q03
  920.       default_button        = '2'
  921.       display_cancel_button = abap_false
  922.       start_column          = 50
  923.       iv_quickinfo_button_1 = TEXT-q04
  924.       iv_quickinfo_button_2 = TEXT-q05
  925.     IMPORTING
  926.       answer                = l_ans
  927.     EXCEPTIONS
  928.       text_not_found        = 1
  929.       OTHERS                = 2.
  930.  
  931.   IF l_ans = '1'.
  932. *--[ Bye Bye Bye
  933.     g_save = abap_false.
  934.     CLEAR sy-subrc.
  935.   ELSE.
  936.     p_subrc = 69.
  937. *      EXIT. "-> Back to the future
  938.   ENDIF.
  939. ENDFORM.
  940.  
  941. FORM bot_crear_estat USING l_code.
  942.   DATA(l_num)   = CONV NUMc2( l_code ).
  943.   DATA(l_stat) = data_config-estat[ l_num ].
  944.   PERFORM data_add_begda_endda USING l_stat-codigo  l_stat-icono l_stat-texto.
  945. ENDFORM.
  946.  
  947. FORM bot_has.
  948.   CLEAR grid_02.
  949.   DATA: l_num TYPE p.
  950.   l_num = sy-datum MOD 7. "sy-datum MOD 7.
  951.   IF l_num > 1.
  952.     l_num -= 1.
  953.   ELSE.
  954.     l_num += 6.
  955.   ENDIF.
  956.   l_num -= 1.
  957.   g_today = sy-datum - l_num.
  958.   PERFORM bot_has_calc USING g_today.
  959.   CALL SCREEN '0300'.
  960. ENDFORM.
  961.  
  962. FORM bot_has_calc USING p_date TYPE sydatum.
  963.   DATA: l_has TYPE ty_has.
  964.   REFRESH t_tab_has.
  965.   DATA(l_low)  = CONV datum( p_date ).
  966.   DATA(l_high) = CONV datum( p_date + 6 ).
  967.   SELECT fecha, proyecto, codigo, SUM( horas ) AS horas  FROM zxx_horas INTO TABLE @DATA(t_tab)
  968.     WHERE fecha >= @p_date
  969.       AND fecha <= @l_high
  970.       AND uname = @sy-uname
  971.     GROUP BY fecha, proyecto, codigo
  972.     ORDER BY fecha ASCENDING, proyecto ASCENDING.
  973.   DATA(l_num) = CONV numc2( '00' ).
  974.   LOOP AT t_tab ASSIGNING FIELD-SYMBOL(<ax>).
  975.     TRY.
  976.         DATA(l_estat) = data_config-estat[ codigo = <ax>-codigo ]-codigo.
  977.         <ax>-proyecto =  <ax>-codigo.
  978.       CATCH cx_root.
  979.     ENDTRY.
  980.     CLEAR <ax>-codigo.
  981.   ENDLOOP.
  982.   DO 6 TIMES.
  983.     l_num = sy-index + 1.
  984.     CLEAR l_has.
  985.     ASSIGN COMPONENT l_num OF STRUCTURE l_has TO FIELD-SYMBOL(<f>).
  986.     LOOP AT t_tab INTO DATA(l_tab) WHERE fecha = l_low.
  987.       <f> = l_tab-horas.
  988.       l_has-proyecto = l_tab-proyecto.
  989.       COLLECT l_has INTO t_tab_has.
  990.     ENDLOOP.
  991.     ADD 1 TO l_low.
  992.   ENDDO.
  993.   CLEAR l_has.
  994.   DATA: l_001(10), l_002(10).
  995.   WRITE p_date TO l_001.
  996.   WRITE l_high TO l_002.
  997.   l_has-proyecto = |Semana del { l_001 } al { l_002 }|.
  998.   INSERT l_has INTO t_tab_has INDEX 1.
  999.  
  1000. ENDFORM.
  1001.  
  1002. FORM bot_week USING p_one_direction.
  1003.   CASE p_one_direction.
  1004.     WHEN '>'. ADD 7 TO g_today.
  1005.     WHEN '<'. SUBTRACT 7 FROM g_today.
  1006.   ENDCASE.
  1007.   PERFORM bot_has_calc USING g_today.
  1008.   grid_03->refresh_table_display( ).
  1009. ENDFORM.
  1010.  
  1011. FORM bot_copy.
  1012.   DATA: index_rows      TYPE lvc_t_row.
  1013.   grid_01->get_selected_rows( IMPORTING et_index_rows = index_rows ).
  1014.   LOOP AT index_rows INTO DATA(l_row) WHERE rowtype IS INITIAL.
  1015.     READ TABLE t_tab_01 INDEX l_row-index INTO DATA(ax).
  1016.     CLEAR ax-indice.
  1017.     DELETE ax-celltab WHERE fieldname = 'FECHA' OR fieldname = 'UNAME'.
  1018.     APPEND ax TO t_tab_01.
  1019.   ENDLOOP.
  1020.   grid_01->refresh_table_display( ).
  1021. ENDFORM.
  1022.  
  1023. FORM bot_copy_modelo.
  1024.   DATA: index_rows      TYPE lvc_t_row.
  1025.   grid_01->get_selected_rows( IMPORTING et_index_rows = index_rows ).
  1026.   DELETE index_rows WHERE rowtype IS NOT INITIAL.
  1027.   IF lines( index_rows ) EQ 1.
  1028.  
  1029.  
  1030.     DATA: t_fields TYPE STANDARD TABLE OF sval,
  1031.           l_ans    TYPE c LENGTH 1.
  1032.     t_fields = VALUE #(
  1033.                         ( tabname = 'ZXX_HORAS' fieldname = 'FECHA' field_obl = abap_true  value = sy-datum fieldtext = 'Fecha final' )
  1034.                       ).
  1035.  
  1036.     CALL FUNCTION 'POPUP_GET_VALUES'
  1037.       EXPORTING
  1038. *       NO_VALUE_CHECK  = ' '
  1039.         popup_title     = 'Fecha final'
  1040.         start_column    = '50'
  1041.         start_row       = '5'
  1042.       IMPORTING
  1043.         returncode      = l_ans
  1044.       TABLES
  1045.         fields          = t_fields
  1046.       EXCEPTIONS
  1047.         error_in_fields = 1
  1048.         OTHERS          = 2.
  1049.  
  1050.     IF l_ans IS INITIAL AND sy-subrc IS INITIAL.
  1051.       DATA(l_dest) = CONV sydatum( t_fields[ 1 ]-value ).
  1052.       DATA(l_max) = CONV sydatum( sy-datum + 365 ). "<.. Protección
  1053.       IF l_dest <= sy-datum OR l_dest > l_max.
  1054.         MESSAGE s398(00) WITH 'La fecha es errónea' '' '' '' DISPLAY LIKE 'E'.
  1055.       ENDIF.
  1056.  
  1057.       DATA t_SPOPLI TYPE STANDARD TABLE OF spopli.
  1058.  
  1059.       SELECT 'X' AS selflag,
  1060.              langt AS varoption
  1061.         FROM t246 INTO CORRESPONDING FIELDS OF TABLE @t_spopli WHERE sprsl = @sy-langu ORDER BY wotnr.
  1062.       t_spopli[ 7 ]-inactive = abap_true. t_spopli[ 7 ]-selflag = abap_false.
  1063.       t_spopli[ 6 ]-inactive = abap_true. t_spopli[ 6 ]-selflag = abap_false.
  1064.       CALL FUNCTION 'POPUP_TO_DECIDE_LIST'
  1065.         EXPORTING
  1066. *         CURSORLINE         = 1
  1067.           mark_flag          = abap_true
  1068.           mark_max           = 6
  1069.           start_col          = 50
  1070.           start_row          = 5
  1071.           textline1          = 'Maque los días a repetir la tarea'
  1072.           titel              = 'Días de repetición'
  1073. *         DISPLAY_ONLY       = ' '
  1074.         IMPORTING
  1075.           answer             = l_ans
  1076.         TABLES
  1077.           t_spopli           = t_SPOPLI
  1078.         EXCEPTIONS
  1079.           not_enough_answers = 1
  1080.           too_much_answers   = 2
  1081.           too_much_marks     = 3
  1082.           OTHERS             = 4.
  1083.  
  1084.       IF sy-subrc <> 0 OR l_ans IS NOT INITIAL.
  1085.         EXIT.
  1086.       ENDIF.
  1087.       TRY.
  1088.           DATA(l_val) = t_spopli[ selflag = abap_true ].
  1089.         CATCH cx_root.
  1090.           MESSAGE s398(00) WITH 'Debe marcar algunos días' '' '' '' DISPLAY LIKE 'E'.
  1091.           EXIT.
  1092.       ENDTRY.
  1093.  
  1094.  
  1095.       DATA: al TYPE cind.
  1096.       LOOP AT index_rows INTO DATA(l_row) WHERE rowtype IS INITIAL.
  1097.         READ TABLE t_tab_01 INDEX l_row-index INTO DATA(ax).
  1098.         CLEAR ax-indice.
  1099.         DELETE ax-celltab WHERE fieldname = 'FECHA' OR fieldname = 'UNAME'.
  1100.         DO.
  1101.           ax-fecha = ax-fecha + 1.
  1102.           CALL FUNCTION 'DATE_COMPUTE_DAY'
  1103.             EXPORTING
  1104.               date = ax-fecha
  1105.             IMPORTING
  1106.               day  = al.
  1107.           CHECK al NA '67'.
  1108.           CHECK t_spopli[ al ]-selflag = abap_true.
  1109.           APPEND ax TO t_tab_01.
  1110.           g_save = abap_true.
  1111.           IF ax-fecha >= l_Dest.
  1112.             EXIT.
  1113.           ENDIF.
  1114.         ENDDO.
  1115.       ENDLOOP.
  1116.       grid_01->refresh_table_display( ).
  1117.     ENDIF.
  1118.   ELSE.
  1119.     MESSAGE s398(00) WITH 'Sólo puede seleccionar un registro' '' '' '' DISPLAY LIKE 'E'.
  1120.   ENDIF.
  1121. ENDFORM.
  1122.  
  1123. FORM bot_crea_param USING p_mod.
  1124.  
  1125.   DATA(t_val) = VALUE ty_sval( tabname = 'ZXX_HORAS' field_obl = abap_true
  1126.                                ( fieldname = 'ASIGNADO_L'
  1127.                                  fieldtext = SWITCH #( p_mod
  1128.                                           WHEN 'P' THEN 'Proyecto'
  1129.                                           WHEN 'M' THEN 'Módulo'
  1130.                                           WHEN 'T' THEN 'Tipo Tarea'
  1131.                                           WHEN 'E' THEN 'Estado' ) )
  1132.                                ( FIELdname = 'DESCR' fieldtext = 'Descripción' )
  1133.                              ).
  1134.  
  1135.   DATA(lv_return) = abap_false.
  1136.   DATA(l_titulo) = |{ TEXT-t02 } { t_val[ 1 ]-fieldtext }|.
  1137.   CALL FUNCTION 'POPUP_GET_VALUES'
  1138.     EXPORTING
  1139.       popup_title     = l_titulo
  1140.     IMPORTING
  1141.       returncode      = lv_return
  1142.     TABLES
  1143.       fields          = t_val
  1144.     EXCEPTIONS
  1145.       error_in_fields = 1
  1146.       OTHERS          = 2.
  1147.  
  1148.   CHECK sy-subrc EQ 0 AND lv_return IS INITIAL.
  1149.  
  1150.   DATA(l_dom) = SWITCH #( p_mod
  1151.                             WHEN 'P' THEN 'ZXX_D_PROYECTO'
  1152.                             WHEN 'M' THEN 'ZXX_D_MODULO'
  1153.                             WHEN 'T' THEN 'ZXX_D_TIPO'
  1154.                             WHEN 'E' THEN 'ZXX_D_STATUS' ).
  1155.  
  1156.   SELECT MAX( valpos ) INTO @DATA(l_max) FROM dd07l WHERE domname = @l_dom.
  1157.   l_max = l_max + 1.
  1158.  
  1159.   DATA(l_dd07l) = VALUE dd07l( domname = l_dom
  1160.                          as4local = 'A'
  1161.                          valpos   = l_max
  1162.                          as4vers  = '0000'
  1163.                          domvalue_l = to_upper( t_val[ 1 ]-value ) ).
  1164.  
  1165.   DATA(l_dd07T) = VALUE dd07t( domname = l_dom
  1166.                                ddlanguage = sy-langu
  1167.                                as4local = 'A'
  1168.                                valpos   = l_max
  1169.                                as4vers  = '0000'
  1170.                                ddtext     = t_val[ 2 ]-value
  1171.                                domvalue_l = to_upper( t_val[ 1 ]-value ) ).
  1172.  
  1173.   SELECT SINGLE * FROM dd07l INTO @DATA(l_kk) "<-- Sí, lo sé, no es profesional
  1174.                 WHERE domname = @l_dom AND
  1175.                       domvalue_l = @l_dd07l-domvalue_l.
  1176.   CHECK sy-subrc NE 0.
  1177.   MODIFY dd07l FROM l_dd07l.
  1178.   MODIFY dd07t FROM l_dd07t.
  1179.  
  1180. ENDFORM.
  1181.  
  1182. FORM data_add_begda_endda USING p_texto p_icono p_descr.
  1183.  
  1184.   DATA(t_val) = VALUE ty_sval( tabname = 'ZXX_HORAS'
  1185.                                field_obl = abap_true
  1186.                                ( fieldname = 'BEGDATE' fieldtext = 'Fecha Desde' )
  1187.                                ( fieldname = 'ENDDATE' fieldtext = 'Fecha hasta' )
  1188.                               ).
  1189.   DATA(lv_return) = abap_false.
  1190.   DATA(l_titulo) = |{ TEXT-t02 } { p_descr }|.
  1191.   CALL FUNCTION 'POPUP_GET_VALUES'
  1192.     EXPORTING
  1193.       popup_title     = l_titulo
  1194.     IMPORTING
  1195.       returncode      = lv_return
  1196.     TABLES
  1197.       fields          = t_val
  1198.     EXCEPTIONS
  1199.       error_in_fields = 1
  1200.       OTHERS          = 2.
  1201.   IF sy-subrc EQ 0 AND lv_return IS INITIAL.
  1202.     DATA(l_begda) = CONV sydatum( t_val[ 1 ]-value ).
  1203.     DATA(l_endda) = CONV sydatum( t_Val[ 2 ]-value ).
  1204.  
  1205.     IF l_begda > l_endda.
  1206.       MESSAGE s398(00) WITH TEXT-e03.
  1207.       EXIT.
  1208.     ENDIF.
  1209.     DATA(l_rest)  = l_endda - l_begda.
  1210.     IF l_rest > data_config-days_before.
  1211.       MESSAGE s398(00) WITH TEXT-e04.
  1212.       EXIT.
  1213.     ENDIF.
  1214.  
  1215.     DO.
  1216.       t_tab_01 = VALUE #( BASE t_tab_01
  1217.                              ( fecha       = l_begda
  1218.                                uname       = sy-uname
  1219.                                proyecto    = ''
  1220.                                modulo      = ''
  1221.                                codigo      = to_upper( p_texto )
  1222.                                desc_codigo = to_upper( p_descr )
  1223.                                asignado_l  = sy-uname
  1224.                                asignado    = sy-uname
  1225.                                begdate     = l_BEGDA
  1226.                                enddate     = l_begda
  1227.                                horas       = 8
  1228.                                status      = 99
  1229.                                avance      = 100
  1230.                                descr       = |{ to_lower( p_texto ) } solicitado el { sy-datum }|
  1231.                             )
  1232.                         ).
  1233.       ADD 1 TO l_begda.
  1234.       CHECK l_begda > l_endda.
  1235.       g_save = abap_true.
  1236.       EXIT.
  1237.     ENDDO.
  1238.   ENDIF.
  1239.  
  1240.  
  1241. ENDFORM.
  1242.  
  1243. FORM bot_vista_global.
  1244. *--[ Creamos tabla de Planning
  1245.  
  1246.   DATA(m_tab) = t_tab_01.
  1247.   SORT m_tab BY fecha ASCENDING.
  1248.   DATA(l_ano_ini) = CONV numc4( m_tab[ 1 ]-fecha+0(4) ).
  1249.   SORT m_tab BY fecha DESCENDING.
  1250.   DATA(l_ano_fin) = CONV numc4( m_tab[ 1 ]-fecha+0(4) ).
  1251.   REFRESH t_tab_03.
  1252.   DO.
  1253.  
  1254.     DO 12 TIMES.
  1255.       DATA(l_mes) = CONV numc2( sy-index ).
  1256.  
  1257.       LOOP AT t_tab_01 INTO DATA(l_data) GROUP BY l_data-uname.
  1258.  
  1259.         t_tab_03 = VALUE #( BASE t_tab_03 ( gjahr     = l_ano_ini
  1260.                                             mes       = l_mes
  1261.                                             uname     = l_data-uname
  1262.                                             uname_txt = l_data-uname_txt ) ).
  1263.  
  1264.       ENDLOOP.
  1265.     ENDDO.
  1266.     l_ano_ini += 1.
  1267.     CHECK l_ano_ini > l_ano_fin.
  1268.     EXIT.
  1269.   ENDDO.
  1270.  
  1271. *--[ Rellenamos tabla de planning
  1272.  
  1273.   LOOP AT t_tab_01 INTO l_data.
  1274.  
  1275.     READ TABLE T_tAB_03 ASSIGNING FIELD-SYMBOL(<f>) WITH KEY gjahr = l_data-fecha+0(4)
  1276.                                                              mes   = l_data-fecha+4(2)
  1277.                                                              uname = l_data-uname.
  1278.     DATA(l_Reg) = |<f>-DIA_{ l_data-fecha+6(2) }|.
  1279.     ASSIGN (l_reg) TO FIELD-SYMBOL(<Ff>).
  1280.     CHECK sy-subrc EQ 0.
  1281.  
  1282.     TRY.
  1283.         DATA(ax) = data_config-estat[ codigo = l_data-codigo ].
  1284.         <ff> = ax-icono.
  1285.         <f>-cellcolor = VALUE #( BASE <f>-cellcolor ( fname = l_Reg+4 color-col = ax-color color-int = 1 color-inv = 0 ) ).
  1286.       CATCH cx_root.
  1287.         <ff> = icon_working_plan.
  1288.     ENDTRY.
  1289.  
  1290.     <f>-total += l_data-horas.
  1291.     AT LAST.
  1292.       DELETE t_tab_03 WHERE total IS INITIAL.
  1293.     ENDAT.
  1294.   ENDLOOP.
  1295.  
  1296.   LOOP AT t_tab_03 INTO DATA(l_data_ano) GROUP BY l_data_ano-gjahr.
  1297.  
  1298.     DO 12 TIMES.
  1299.       l_mes = CONV numc2( sy-index ).
  1300.  
  1301.       READ TABLE t_tab_03 TRANSPORTING NO FIELDS WITH KEY gjahr = l_Data_ano-gjahr
  1302.                                                           mes   = l_mes.
  1303.       CHECK sy-subrc EQ 0.
  1304.  
  1305.       DO 31 TIMES.
  1306.         DATA(l_dia) = CONV numc2( sy-index ).
  1307.         TRY.
  1308.  
  1309.             DATA(l_fecha) = CONV sydatum( |{ l_data_ano-gjahr }{ l_mes }{ l_dia }| ).
  1310.           CATCH cx_root.
  1311.             CONTINUE.
  1312.         ENDTRY.
  1313.  
  1314. *--[ Sí, lo sé, se puede optimizar sumando 7 días, si lo estás leyendo, hazlo tú :D
  1315.         DATA: l_tipo TYPE p.
  1316.         CALL FUNCTION 'DAY_IN_WEEK'
  1317.           EXPORTING
  1318.             datum = l_fecha
  1319.           IMPORTING
  1320.             wotnr = l_tipo.
  1321.         .
  1322.         CHECK l_tipo > 5 OR
  1323.         ( l_fecha+4(4) IN data_config-t_fest AND lines( data_config-t_fest ) > 0 ) OR
  1324.         ( l_fecha IN data_config-t_festfull AND lines( data_config-t_festfull ) > 0 ).
  1325.         DATA(l_dia_txt) = |DIA_{ l_dia }|.
  1326.         LOOP AT t_tab_03 ASSIGNING FIELD-SYMBOL(<ax>) WHERE gjahr = l_data_ano-gjahr AND
  1327.                                                             mes   = l_mes.
  1328.           <ax>-cellcolor = VALUE #( BASE <ax>-cellcolor ( fname = l_dia_txt color-col = 7 color-int = 1 color-inv = 0 ) ).
  1329.         ENDLOOP.
  1330.       ENDDO.
  1331.  
  1332.     ENDDO.
  1333.  
  1334.   ENDLOOP.
  1335.  
  1336.   CALL SCREEN '0200' STARTING AT 5 5 ENDING AT 190 25.
  1337. ENDFORM.
  1338.  
  1339. ****# Fichero de configuración para el programa Z_XX_PRG_HORAS
  1340. ****
  1341. ****# Fichero de configuración para el programa Z_XX_PRG_HORAS
  1342. ****
  1343. ****[Seguridad]
  1344. ****# Definimos los SuperUsuarios
  1345. ****SuperUSER ALEX  # Alex
  1346. ****
  1347. ****[Constantes]
  1348. ****Days_Before 90
  1349. ****HAS_Url https://
  1350. ****JIRA_Url http://jira.XXX.es/browse/
  1351. ****
  1352. ****#Campos a cargar por defecto, con el siguiente formato
  1353. ****#Default [NOMBRE_DEL_CAMPO] [VALOR_O_VARIABLE_SISTEMA]
  1354. ****Default PROYECTO XXXX
  1355. ****Default MODULO XX
  1356. ****Default STATUS 30
  1357. ****Default AVANCE 10
  1358. ****Default ASIGNADO SY-UNAME
  1359. ****DEfault BEGDATE SY-DATUM
  1360. ****
  1361. ****[Estadisticos]
  1362. ****# Valores Estadisticos posibles
  1363. ****
  1364. ****# Codigo;Icono;Color;Texto
  1365. ****ESTAT VACACIONES;@IQ@;5;Vacaciones
  1366. ****ESTAT ENFERMEDAD;@IP@;6;Enfermedad
  1367. ****ESTAT OTROS;@3P@;3;Otros Valores
  1368. ****
  1369. ****[Calendario]
  1370. ****Festivos_MMDD 0101;0106;0501;0815;1012
  1371. ****Festivos_MMDD 1101;1206;1208;1224;1225;1231
  1372. ****
  1373. ****Festivos_AAAAMMDD 20250319;20250418;20250421
  1374. ****Festivos_AAAAMMDD 20251009
  1375. ****