CATS, CATSDB, CATSCO

Esta classe lê dados de uma tabela Z e cria ou apaga apontamentos na transação CATS e também transferências dos apontamentos realizados com sucesso para CO.

CLASS zcl_apontamento_horas_new DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    TYPES:
      ty_r_project_id  TYPE RANGE OF zwfs_allocation-project_id .
    TYPES:
      ty_r_zdate       TYPE RANGE OF zwfs_allocation-zdate .
    TYPES:
      ty_r_batch_id   TYPE RANGE OF zwfs_allocation-batch_id .
    TYPES:
      ty_r_record_id   TYPE RANGE OF zwfs_allocation-record_id .
    TYPES:
      ty_r_employee_id TYPE RANGE OF zwfs_allocation-employee_id .
    TYPES:
      ty_r_erdat       TYPE RANGE OF zwfs_allocation-erdat .
    TYPES:
      ty_r_aedat       TYPE RANGE OF zwfs_allocation-aedat .
    TYPES:
      ty_r_pay_code    TYPE RANGE OF zwfs_allocation-pay_code .
    TYPES:
      ty_r_status      TYPE RANGE OF zwfs_allocation-status .
    TYPES:
      ty_t_allocation TYPE STANDARD TABLE OF zst_allocation_salv
                        WITH NON-UNIQUE KEY mandt batch_id record_id .

    DATA r_project_id TYPE ty_r_project_id .
    DATA r_zdate TYPE ty_r_zdate .
    DATA r_batch_id TYPE ty_r_batch_id .
    DATA r_record_id TYPE ty_r_record_id .
    DATA r_employee_id TYPE ty_r_employee_id .
    DATA r_erdat TYPE ty_r_erdat .
    DATA r_aedat TYPE ty_r_aedat .
    DATA r_pay_code TYPE ty_r_pay_code .
    DATA r_status TYPE ty_r_status .
    CLASS-DATA mo_allocation TYPE REF TO zcl_apontamento_horas_new .

    CLASS-METHODS factory
      RETURNING
        VALUE(ro_allocation) TYPE REF TO zcl_apontamento_horas_new .
    METHODS constructor
      IMPORTING
        !process_type TYPE abap_bool OPTIONAL
        !testrun      TYPE abap_bool OPTIONAL .
    METHODS executar
      RETURNING
        VALUE(results) TYPE ztt_allocation_without_key .
    METHODS get_data
      RETURNING
        VALUE(rt_alloc) TYPE ztt_allocation .
    METHODS reprocessar
      IMPORTING
        !it_allocation TYPE ty_t_allocation .
    METHODS selecionar_apontamentos .
    METHODS selecionar_reprocessamento
      IMPORTING
        !it_allocation TYPE ty_t_allocation .
    METHODS set_filter
      IMPORTING
        !it_project_id  TYPE ty_r_project_id OPTIONAL
        !it_zdate       TYPE ty_r_zdate OPTIONAL
        !it_batch_id    TYPE ty_r_batch_id OPTIONAL
        !it_record_id   TYPE ty_r_record_id OPTIONAL
        !it_employee_id TYPE ty_r_employee_id OPTIONAL
        !it_erdat       TYPE ty_r_erdat OPTIONAL
        !it_aedat       TYPE ty_r_aedat OPTIONAL
        !it_pay_code    TYPE ty_r_pay_code OPTIONAL
        !it_status      TYPE ty_r_status OPTIONAL .
    METHODS set_mt_allocation
      IMPORTING
        !it_allocation TYPE ztt_allocation .
    METHODS redefinir
      IMPORTING
        !it_allocation TYPE ztt_allocation
        !iv_status     TYPE zwfs_status .
  PROTECTED SECTION.

    DATA _ersda TYPE catsdb-ersda .
    DATA _erstm TYPE catsdb-erstm .
    DATA _handle TYPE balloghndl .
    DATA _process_type TYPE abap_bool .
    DATA _testrun TYPE abap_bool .

  PRIVATE SECTION.

    TYPES:
      tt_bapicats1 TYPE STANDARD TABLE OF bapicats1 WITH DEFAULT KEY .
    TYPES:
      BEGIN OF ENUM ty_e_status BASE TYPE n ,
        new        VALUE IS INITIAL,
        processing VALUE 1,
        error      VALUE 2,
        success    VALUE 3,
        eliminado  VALUE 4,
        migrar_co  VALUE 5,
        waiting    VALUE 6,
      END OF ENUM ty_e_status .
    TYPES:
      BEGIN OF ty_s_catsco,
        counter   TYPE catsco-counter,
        stokz     TYPE catsco-stokz,
        pernr     TYPE catsco-pernr,
        workdate  TYPE catsco-workdate,
        catshours TYPE catsco-catshours,
        belnr     TYPE catsco-belnr,
        transfer  TYPE catsco-transfer,
      END OF ty_s_catsco .
    TYPES:
      ty_t_catsco TYPE SORTED TABLE OF ty_s_catsco
                         WITH UNIQUE KEY counter
                         WITH NON-UNIQUE SORTED KEY migrar COMPONENTS pernr workdate belnr .
    TYPES ty_s_catsdb TYPE catsdb .
    TYPES:
      ty_t_catsdb TYPE SORTED TABLE OF ty_s_catsdb
                            WITH UNIQUE KEY counter
                            WITH NON-UNIQUE SORTED KEY ltxa1 COMPONENTS ltxa1 .
    TYPES:
      BEGIN OF ty_s_workdate,
        pernr     TYPE pa0000-pernr,
        workdate  TYPE catsdb-workdate,
        catshours TYPE catsdb-catshours,
      END OF ty_s_workdate .
    TYPES:
      ty_t_workdates TYPE SORTED TABLE OF ty_s_workdate
                                       WITH UNIQUE KEY pernr workdate .
    TYPES:
      ty_r_pernr TYPE RANGE OF catsdb-pernr .
    TYPES:
      ty_r_belnr TYPE RANGE OF catsdb-belnr .
    TYPES:
      ty_r_wdate TYPE RANGE OF catsdb-workdate .

    CONSTANTS c_extra TYPE zwfs_pay_code VALUE 'PROJ_HOURS_OT' ##NO_TEXT.
    CONSTANTS c_proj_name TYPE char8 VALUE 'PROJ_PWC' ##NO_TEXT.
    DATA mt_allocation TYPE ztt_allocation .
    DATA mt_catsco TYPE ty_t_catsco .
    DATA mt_catsdb TYPE ty_t_catsdb .
    DATA mt_migra_co TYPE ztt_allocation_std_without_key .
    DATA mt_results TYPE ztt_allocation_without_key .
    DATA mt_return TYPE bapiret2_tab .
    DATA mt_workdates TYPE ty_t_workdates .
    DATA mt_apontados TYPE ztt_allocation_without_key .
    DATA mt_zwfs_allocation TYPE ztt_allocation_without_key .

    METHODS add_time
      IMPORTING
        !startdate TYPE datum
        !starttime TYPE enduz
        !addtime   TYPE thour
      EXPORTING
        !enddate   TYPE datum
        !endtime   TYPE enduz .
    METHODS apontar .
    METHODS buscar_projetos .
    METHODS chamar_bapi_para_apontar
      IMPORTING
        !it_catsrecords TYPE tt_bapicats1 .
    METHODS chamar_bapi_para_eliminar
      IMPORTING
        !it_catsrecords TYPE cats_esa_delete_rec_t .
    METHODS destravar_apontamentos .
    METHODS eliminar_apontamentos .
    METHODS esperar_transferencia_co
      IMPORTING
        !it_pernr    TYPE ty_r_pernr OPTIONAL
        !it_belnr    TYPE ty_r_belnr OPTIONAL
        !it_wdate    TYPE ty_r_wdate OPTIONAL
        !it_migra_co TYPE ztt_allocation_std_without_key OPTIONAL .
    METHODS get_proj_status
      IMPORTING
        !i_projid       TYPE zwfs_project_id
      RETURNING
        VALUE(r_status) TYPE bapi_user_status_text .
    METHODS limpar_dados .
    METHODS migrar_dados_co
      IMPORTING
        !it_migra_co  TYPE ztt_allocation_std_without_key
      RETURNING
        VALUE(result) TYPE abap_bool .
    METHODS selecionar_wfs_allocation .
    METHODS travar_apontamentos .
    METHODS executar_job_migrar_co
      IMPORTING
        !it_pernr          TYPE ty_r_pernr OPTIONAL
        !it_belnr          TYPE ty_r_belnr OPTIONAL
        !it_wdate          TYPE ty_r_wdate OPTIONAL
        !iv_count          TYPE i
      RETURNING
        VALUE(rv_finished) TYPE abap_bool .
ENDCLASS.



CLASS zcl_apontamento_horas_new IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->ADD_TIME
* +-------------------------------------------------------------------------------------------------+
* | [--->] STARTDATE                      TYPE        DATUM
* | [--->] STARTTIME                      TYPE        ENDUZ
* | [--->] ADDTIME                        TYPE        THOUR
* | [<---] ENDDATE                        TYPE        DATUM
* | [<---] ENDTIME                        TYPE        ENDUZ
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD add_time.

    CALL FUNCTION 'CATT_ADD_TO_TIME'
      EXPORTING
        idate = startdate
        itime = starttime
        stdaz = addtime
      IMPORTING
        edate = enddate
        etime = endtime.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->APONTAR
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD apontar.

    MESSAGE i067 INTO DATA(dummy).
    LOG-POINT ID zps20 FIELDS dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    DATA lt_catsrecords TYPE STANDARD TABLE OF bapicats1.
    DATA(lv_continue) = abap_false.

    LOOP AT mt_allocation ASSIGNING FIELD-SYMBOL(<key>)
                          USING KEY operation
                          WHERE operation = CONV zwfs_operation( 1 )
                          GROUP BY ( type = <key>-type
                                     code = <key>-pay_code
                                     stat = <key>-status
                                     indx = GROUP INDEX
                                     size = GROUP SIZE )

                          ASSIGNING FIELD-SYMBOL(<group>).

      CHECK <group>-type IS NOT INITIAL. "ORDEM, PEP
      "Somente esses Status podem ser re/processados
      CHECK <group>-stat = CONV zwfs_status( new ) OR
            <group>-stat = CONV zwfs_status( processing ) OR
            <group>-stat = CONV zwfs_status( error ).

      LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<allocation>).

        TRY.

            IF lv_continue = abap_true.
              lv_continue = abap_false.
              CONTINUE.
            ENDIF.

            <allocation>-status = CONV #( processing ).

            IF VALUE #( mt_catsdb[ KEY ltxa1 ltxa1 = CONV catsshortt( |{ <allocation>-batch_id }{ <allocation>-record_id }| ) ] OPTIONAL ) IS NOT INITIAL OR
               VALUE #( mt_catsdb[ KEY ltxa1 ltxa1 = CONV catsshortt( |{ <allocation>-batch_id }_{ <allocation>-record_id }| ) ] OPTIONAL ) IS NOT INITIAL.
              <allocation>-status = CONV #( success ).
              CONTINUE.
            ENDIF.

            DATA(workdate) = <allocation>-zdate.
            DATA(saldo) = <allocation>-zhour.
*        DATA(available) = COND d( WHEN <allocation>-zhour > 24 THEN |{ <allocation>-zdate(6) }01| ELSE <allocation>-zdate ).
            DATA(available) = <allocation>-zdate.

            WHILE saldo > 0.

              DATA(catshours) = COND catsdb-catshours( WHEN <allocation>-zhour < 24 THEN <allocation>-zhour
                                                       WHEN saldo < 22 THEN saldo
                                                       ELSE 22 ).
*          DATA(catshours) = <allocation>-zhour.

              IF ( saldo = <allocation>-zhour ) AND ( <allocation>-zhour > 24 ).
                INSERT VALUE #( pernr = <allocation>-pernr workdate = <allocation>-zdate catshours = catshours ) INTO TABLE mt_workdates.
                workdate = <allocation>-zdate.
              ELSE.
                DATA(indx) = line_index( mt_workdates[ pernr = <allocation>-pernr workdate = available ] ).
                IF indx > 0.
                  LOOP AT mt_workdates ASSIGNING FIELD-SYMBOL(<workdate>)
                                       FROM indx
                                       WHERE pernr = <allocation>-pernr.
                    IF <workdate>-workdate > available.
                      EXIT.
                    ELSEIF <workdate>-catshours >= 22.
                      available += 1.
                    ELSE.
                      catshours = COND #( WHEN ( 22 - <workdate>-catshours ) > saldo THEN saldo ELSE ( 22 - <workdate>-catshours ) ).
                      <workdate>-catshours += catshours.
                    ENDIF.
*                    IF <workdate>-workdate > available.
*                      EXIT.
*                    ELSEIF catshours >= 22.
*                      available += 1.
*                    ELSE.
*                      catshours = COND #( WHEN ( 22 - <workdate>-catshours ) >= catshours THEN catshours ELSE catshours - ( 22 - <workdate>-catshours ) ).
*                      <workdate>-catshours += catshours.
*                    ENDIF.
                  ENDLOOP.
                ENDIF.
                IF saldo <= catshours.
                  catshours = saldo.
                ENDIF.
                INSERT VALUE #( pernr = <allocation>-pernr workdate = available catshours = catshours ) INTO TABLE mt_workdates.
                workdate = available.
              ENDIF.

              add_time(
                EXPORTING
                  startdate = <allocation>-zdate
                  starttime = `000000`
                  addtime   = CONV #( catshours )
                IMPORTING
                  endtime   = DATA(endtime) ).   "#EC NEEDED

              DATA(ls_catsrecord) = VALUE bapicats1(
                                workdate = workdate
                          employeenumber = <allocation>-pernr
                               send_cctr = <allocation>-kostl
                                 acttype = <allocation>-lstar
                         extra_pay_indic = COND #( WHEN <allocation>-pay_code = c_extra THEN `+` ELSE abap_false )
                               rec_order = COND #( WHEN <group>-type = `ORDEM` THEN  <allocation>-objnr ELSE abap_false )
                             wbs_element = COND #( WHEN <group>-type = `PEP` THEN  <allocation>-objnr ELSE abap_false )
                               catshours = catshours
*                           starttime = `000000`
                                    unit = `H`
                            isocode_unit = `H`
                            abs_att_type = `0800`
*                             endtime = endtime
                               shorttext = |{ <allocation>-batch_id }{ <allocation>-record_id }| ).

              INSERT ls_catsrecord INTO TABLE lt_catsrecords.

              SUBTRACT catshours FROM saldo.

            ENDWHILE.

          CATCH cx_dynamic_check INTO DATA(lx_dynamic).

            <allocation>-status = CONV #( error ).
            <allocation>-message = lx_dynamic->get_longtext( ).
            <allocation>-aedat = sy-datum.
            <allocation>-aezet = sy-uzeit.
            <allocation>-aenam = sy-uname.
            <allocation>-processing_time = utclong_current( ).
            DATA(alloc) = CORRESPONDING zwfs_allocation( <allocation> ).
            UPDATE zwfs_allocation FROM alloc.

            lv_continue = abap_true.
            RETRY.


        ENDTRY.

      ENDLOOP.


      IF lt_catsrecords IS NOT INITIAL.

* Executa a BAPI em blocos de documentos
        chamar_bapi_para_apontar( lt_catsrecords ).

      ENDIF.

      CLEAR:
        lt_catsrecords,
        mt_workdates,
        mt_return.

    ENDLOOP.



  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->BUSCAR_PROJETOS
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD buscar_projetos.

    LOG-POINT ID zps20 FIELDS mt_migra_co.

*    CHECK mt_migra_co[] IS NOT INITIAL.

    MESSAGE i070 INTO DATA(dummy).
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    DATA(timer) = cl_abap_runtime=>create_hr_timer( ).
    DATA(t1) = timer->get_runtime( ).

    DATA lt_migra_co TYPE ztt_allocation_std_without_key.
    DATA lt_migra_co_pendentes TYPE ztt_allocation_std_without_key.
    DATA(type) = CONV zst_allocation-type( `PEP` ).

*    lt_migra_co = VALUE #(
*                    LET _migrar = FILTER #( mt_allocation USING KEY status WHERE status = CONV zwfs_status( migrar_co ) )
*                     IN
*                ( LINES OF FILTER #( _migrar EXCEPT IN mt_migra_co WHERE mandt = mandt AND batch_id = batch_id AND record_id = record_id ) ) ).

    lt_migra_co_pendentes = mt_migra_co[].
    lt_migra_co_pendentes = VALUE #(
                             BASE lt_migra_co_pendentes
                          ( LINES OF FILTER #(
                                     FILTER #( mt_allocation USING KEY status WHERE status = CONV zwfs_status( migrar_co ) )
                                     EXCEPT IN mt_migra_co WHERE mandt = mandt
                                                             AND batch_id = batch_id
                                                             AND record_id = record_id
                                                             AND employee_id = employee_id
                                                             AND counter = counter
                                                             AND belnr = belnr ) ) ).

    lt_migra_co_pendentes = VALUE #(
                             BASE lt_migra_co_pendentes
                          ( LINES OF FILTER #(
                                     FILTER #( mt_allocation USING KEY status WHERE status = CONV zwfs_status( waiting ) )
                                     EXCEPT IN mt_migra_co WHERE mandt = mandt
                                                             AND batch_id = batch_id
                                                             AND record_id = record_id
                                                             AND employee_id = employee_id
                                                             AND counter = counter
                                                             AND belnr = belnr ) ) ).


    MESSAGE i057 INTO dummy.
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

*    LOOP AT mt_migra_co ASSIGNING FIELD-SYMBOL(<migrar>)
*                        USING KEY type.
    LOOP AT lt_migra_co_pendentes ASSIGNING FIELD-SYMBOL(<migrar>) USING KEY type.

      cl_progress_indicator=>progress_indicate(
        EXPORTING
          i_text               = |{ dummy } { sy-tabix } / { lines( mt_migra_co ) }|
          i_processed          = sy-tabix
          i_total              = lines( mt_migra_co )
          i_output_immediately = abap_true ).

      <migrar>-aedat = sy-datum.
      <migrar>-aezet = sy-uzeit.
      <migrar>-aenam = sy-uname.
      <migrar>-processing_time = utclong_current( ).

      CHECK <migrar>-type = 'PEP'.

      IF <migrar>-type = type.
        CASE <migrar>-profl.
          WHEN 'ZPS0001'.
            DATA(ls_status) =  get_proj_status( <migrar>-project_id ).
            IF ls_status = 'PREP'.
              <migrar>-status = CONV #( waiting ).
              UPDATE zwfs_allocation FROM <migrar>.
            ELSE.
              INSERT <migrar> INTO TABLE lt_migra_co.
            ENDIF.

          WHEN 'ZPS0002'.
            INSERT <migrar> INTO TABLE lt_migra_co.

          WHEN OTHERS.
            <migrar>-status = CONV #( success ).
            UPDATE zwfs_allocation FROM <migrar>.

        ENDCASE.
      ELSE.
        <migrar>-status = CONV #( success ).
        UPDATE zwfs_allocation FROM <migrar>.
      ENDIF.

    ENDLOOP.

    mt_results = FILTER ztt_allocation_without_key( mt_migra_co USING KEY status WHERE status = CONV #( success ) ).
    mt_results = VALUE #(
                  BASE mt_results
               ( LINES OF FILTER #( lt_migra_co
                          EXCEPT IN mt_migra_co
                           WHERE mandt = mandt
                             AND batch_id = batch_id
                             AND record_id = record_id
                             AND employee_id = employee_id
                             AND counter = counter
                             AND belnr = belnr
                              ) ) ).

* Alterar status dos itens migrados (os demais ja estarao com status atualizados
    LOG-POINT ID zps20 FIELDS lt_migra_co.
    IF lt_migra_co IS NOT INITIAL.

      MESSAGE i058 INTO dummy.
      zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

      migrar_dados_co( lt_migra_co ).
    ENDIF.

    DATA(t2) = timer->get_runtime( ).
    MESSAGE i099 WITH |{ ( t2 - t1 ) / 1000 }| INTO dummy.
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

    MESSAGE i071 WITH |{ lines( lt_migra_co ) }| INTO dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_APONTAMENTO_HORAS_NEW->CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* | [--->] PROCESS_TYPE                   TYPE        ABAP_BOOL(optional)
* | [--->] TESTRUN                        TYPE        ABAP_BOOL(optional)
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD constructor.
    _ersda = sy-datum.
    _erstm = sy-uzeit.
    _handle = zcl_ptool_helper=>bal_log_create( iv_object    = `ZPS`
                                                iv_subobject = `APONTAMENTO` ).
    _process_type = process_type.
    _testrun = testrun.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->ELIMINAR_APONTAMENTOS
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD eliminar_apontamentos.

    DATA lt_eliminar TYPE ztt_allocation.
    DATA lt_catsrecords TYPE cats_esa_delete_rec_t.

    MESSAGE i065 INTO DATA(dummy).
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

*    DATA(lt_peps) = FILTER #( mt_allocation USING KEY type WHERE type = CONV #( 'PEP' ) AND operation = CONV #( '0' )  ).
    SELECT DISTINCT
*           z~batch_id, z~record_id, z~project_id,
*           a~usrid,
*           b~kostl,
*           d~lstar,
*           c~counter, c~pernr, c~workdate, c~rproj, c~status, c~belnr, c~catshours
           c~counter, c~extsystem, c~extapplication, c~extdocumentno
      FROM @mt_allocation AS z
      JOIN pa0105 AS a ON   a~usrid = z~employee_id
                      AND   a~subty = '0002'
                      AND ( a~endda >= @sy-datum AND a~begda <= @sy-datum )
      JOIN pa0001 AS b ON   b~pernr = a~pernr
                      AND ( b~endda >= @sy-datum AND b~begda <= @sy-datum )
      JOIN pa0315 AS d ON   d~pernr = a~pernr
                      AND ( d~endda >= @sy-datum AND d~begda <= @sy-datum )
      JOIN prps   AS p ON p~posid_edit = z~project_id
      JOIN catsdb AS c ON c~pernr = a~pernr
                      AND c~rproj = p~pspnr
                      AND c~record_id = z~record_id
         WHERE z~type      = 'PEP'
           AND z~operation = '0'
           AND z~status   IN @r_status[]
           AND c~status   <> '60'
          INTO TABLE @lt_catsrecords.

*    DATA(lt_ordens) = FILTER #( mt_allocation USING KEY type WHERE type = 'ORDEM' AND operation = CONV #( '0' ) ).
    SELECT DISTINCT
           c~counter, c~extsystem, c~extapplication, c~extdocumentno
      FROM @mt_allocation AS z
      JOIN pa0105 AS a ON   a~usrid = z~employee_id
                      AND   a~subty = '0002'
                      AND ( a~endda >= @sy-datum AND a~begda <= @sy-datum )
      JOIN pa0001 AS b ON   b~pernr = a~pernr
                      AND ( b~endda >= @sy-datum AND b~begda <= @sy-datum )
      JOIN pa0315 AS d ON   d~pernr = a~pernr
                      AND ( d~endda >= @sy-datum AND d~begda <= @sy-datum )
      JOIN aufk   AS p ON p~aufnr = z~project_id
      JOIN catsdb AS c ON c~pernr     = a~pernr
                      AND c~raufnr    = p~aufnr
                      AND c~record_id = z~record_id
         WHERE z~type      = 'ORDEM'
           AND z~operation = '0'
           AND z~status   IN @r_status[]
           AND c~status   <> '60'
 APPENDING TABLE @lt_catsrecords.

*    IF mt_catsdb[] IS NOT INITIAL.
*
*      DATA(lt_keys) = VALUE ty_t_allocation(
*                        FOR <key> IN mt_catsdb
*                       ( batch_id = <key>-batch_id
*                        record_id = <key>-record_id ) ).
*
*      SELECT DISTINCT
*             z~*
*        FROM @lt_keys AS i
*        JOIN zwfs_allocation AS z ON z~batch_id = i~batch_id
*                                 AND z~record_id = i~record_id
*       WHERE z~counter IS NOT INITIAL
*        INTO CORRESPONDING FIELDS OF TABLE @lt_eliminar.
*
*    ENDIF.
*
*    DATA(lt_catsrecords) = VALUE cats_esa_delete_rec_t(
**                             FOR <eliminar> IN mt_allocation USING KEY operation WHERE ( operation = CONV zwfs_operation( 0 ) )
*                             FOR <eliminar> IN lt_eliminar USING KEY counter
**                             FOR <catsdb> IN mt_catsdb WHERE ( batch_id = <eliminar>-batch_id AND
**                                                               record_id = <eliminar>-record_id )
**                             FOR <catsdb> IN mt_catsdb
**                                       USING KEY ltxa1
**                                       WHERE ( ltxa1 = CONV catsshortt( |{ <eliminar>-batch_id }{ <eliminar>-record_id }| ) )
**                             LET _counter = VALUE #( mt_apontados[ record_id = <eliminar>-record_id ]-counter OPTIONAL )
**                              IN
*                       ( counter = <eliminar>-counter ) ).
*
*    lt_catsrecords = VALUE cats_esa_delete_rec_t(
*                      BASE lt_catsrecords
*                       FOR <reprocessar> IN mt_allocation USING KEY status WHERE ( status = '0' )
*                       FOR <catsdb> IN mt_catsdb WHERE ( batch_id = <reprocessar>-batch_id AND
*                                                        record_id = <reprocessar>-record_id )
*                     ( counter = <catsdb>-counter ) ).
*
**    lt_catsrecords = VALUE cats_esa_delete_rec_t(
**                      BASE lt_catsrecords
**                       FOR <eliminar> IN mt_allocation USING KEY operation WHERE ( operation = CONV zwfs_operation( 0 ) )
***                       FOR <catsdb> IN mt_catsdb
***                                 USING KEY ltxa1
***                                 WHERE ( ltxa1 = CONV catsshortt( |{ <eliminar>-batch_id }_{ <eliminar>-record_id }| ) )
**                       LET _counter = VALUE #( mt_apontados[ record_id = <eliminar>-record_id ]-counter OPTIONAL )
**                        IN
**                 ( counter = _counter
**             extdocumentno = <catsdb>-belnr
**            extapplication = <catsdb>-extapplication
**                 extsystem = <catsdb>-extsystem ) ).
*
    DELETE ADJACENT DUPLICATES FROM lt_catsrecords.

    chamar_bapi_para_eliminar( it_catsrecords = lt_catsrecords ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_APONTAMENTO_HORAS_NEW->EXECUTAR
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RESULTS                        TYPE        ZTT_ALLOCATION_WITHOUT_KEY
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD executar.
*    DATA: callstack_tab TYPE abap_callstack,
*          syscall_tab   TYPE sys_callst.
*
*    CALL FUNCTION 'SYSTEM_CALLSTACK'
*      IMPORTING
*        callstack    = callstack_tab
*        et_callstack = syscall_tab.
*
*    READ TABLE syscall_tab TRANSPORTING NO FIELDS WITH KEY eventname = 'FUNC'
*                                                           eventtype = 'Z_FM_PS_WFS_APONTAMENTO'.
*    IF sy-subrc = 0.
*      DATA(func) = abap_true.
*    ENDIF.
*
*    CALL FUNCTION 'ENQUEUE_ESTERM'
*      EXPORTING
*        mode_tstc      = 'E'
*        tcode          = 'Z_APONTHORAS_RFC'
*      EXCEPTIONS
*        foreign_lock   = 1
*        system_failure = 2
*        OTHERS         = 3.
*
*    IF sy-subrc = 1.
*      DATA(bloq_rfc) = abap_true.
*    ENDIF.


    MESSAGE i072 INTO DATA(dummy).
    LOG-POINT ID zps20 FIELDS dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    DATA(timer) = cl_abap_runtime=>create_hr_timer( ).
    DATA(t1) = timer->get_runtime( ).

*    IF bloq_rfc IS INITIAL.
* Ler apontamentos para processar
    selecionar_apontamentos( ).

* Trava os registros para evitar conflitos
    travar_apontamentos( ).

* Elimina registros inv�lidos do processamento e grava log
    limpar_dados( ).

* Elimina registros nulos
    eliminar_apontamentos( ).

* Busca projeto e migra dados CO
    buscar_projetos( ).
    CLEAR mt_migra_co.

* Cria apontamentos
    apontar( ).

* Busca projeto e migra dados CO
    buscar_projetos( ).

    destravar_apontamentos( ).

*    ELSE.
*      MESSAGE i000 WITH |Outro processo j� est� em execu��o via RFC|.
*      zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
*      MESSAGE i000 WITH |Processamento abortado|.
*      zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
*      zcl_ptool_helper=>bal_db_save( ).
*
*      IF func IS INITIAL.
*        MESSAGE s000 WITH |Outro processo j� est� em execu��o via RFC| DISPLAY LIKE 'E'.
*      ENDIF.
*    ENDIF.

    DATA(t2) = timer->get_runtime( ).
    MESSAGE i099 WITH |{ ( t2 - t1 ) / 1000 }| INTO dummy.
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

    MESSAGE i073 INTO dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    results = mt_results[].

*    CALL FUNCTION 'DEQUEUE_ESTERM'
*      EXPORTING
*        mode_tstc = 'E'
*        tcode     = 'Z_APONTHORAS_RFC'
*        x_tcode   = ' '
*        _scope    = '3'
*        _synchron = ' '
*        _collect  = ' '.
*    CLEAR bloq_rfc.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->GET_PROJ_STATUS
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_PROJID                       TYPE        ZWFS_PROJECT_ID
* | [<-()] R_STATUS                       TYPE        BAPI_USER_STATUS_TEXT
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD get_proj_status.

    DATA:
      lt_wbs_elements  TYPE STANDARD TABLE OF bapi_wbs_elements,
      lt_system_status TYPE STANDARD TABLE OF bapi_wbs_system_status,
      lt_user_status   TYPE STANDARD TABLE OF bapi_wbs_user_status,

      ls_wbs_elements  TYPE bapi_wbs_elements,
      ls_user_status   TYPE bapi_wbs_user_status.

    ls_wbs_elements-wbs_element = i_projid.
    APPEND ls_wbs_elements TO lt_wbs_elements.

    CALL FUNCTION 'BAPI_BUS2054_GET_STATUS'
      TABLES
        i_wbs_elements  = lt_wbs_elements
        e_system_status = lt_system_status
        e_user_status   = lt_user_status.

    READ TABLE lt_user_status INTO ls_user_status INDEX 1.
    r_status = ls_user_status-user_status.

*    TYPES:
*      ty_r_status TYPE RANGE OF rvari_val_255,
*      ty_r_istat  TYPE RANGE OF istat.
*
*    DATA lt_status TYPE ty_r_status.
*
*    SELECT sign, opti, low, high
*      FROM tvarvc
*     WHERE name = 'ZPS_STATUS_BLOQ'
*       AND type = 'S'
*      INTO TABLE @lt_status.
*
*    SELECT DISTINCT
*           p~pspnr, p~posid, p~posid_edit, p~objnr, j~stat, x~txt04
*      FROM @mt_allocation as i
*      JOIN jest  AS j ON j~objnr = p~objnr
*                     AND j~inact = ' '
*      JOIN tj02  AS t ON t~istat = j~stat
*      JOIN tj02t AS x ON x~istat = t~istat
*                     AND x~spras = 'P'
*     WHERE posid_edit IN ( 'PC.001.0001653-B.002', 'PC.037.0000116-I.001', 'PC.001.0000006-B.001' )
*       AND ( j~istat IN rl_stat1 OR j~istat IN rl_stat1 OR j~istat IN rl_stat1 )
*     ORDER BY p~pspnr, p~posid, p~posid_edit, p~objnr, j~stat
*      INTO TABLE @data(mt_status).
*
*
*    LOOP AT lt_status INTO DATA(ls_status).
*
*      SPLIT ls_status AT '+' INTO TABLE DATA(lt_split).
*      DATA(rl_status) = VALUE ty_r_istat( FOR <status> IN lt_split sign = `I` option = `EQ` ( low = <status>-low ) ).
*
*      select count( * )
*        from @mt_status as i
*       where stat in rl_status
*        into @data(lv_status).
*
*    ENDLOOP.
*



  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->LIMPAR_DADOS
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD limpar_dados.

*    BREAK-POINT.
    MESSAGE i063 INTO DATA(dummy).
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    DATA(timer)  = cl_abap_runtime=>create_hr_timer( ).
    DATA(t1) = timer->get_runtime( ).

    DATA(lt_broken) = VALUE ztt_allocation(
                        FOR <notype> IN FILTER #( mt_allocation USING KEY type WHERE type = '     ' )
                    ( VALUE #(
                       BASE <notype> status = `2`
                                    message = 'N�o foi poss�vel determinar o tipo do apontamento'(004)
                                      aedat = sy-datum
                                      aezet = sy-uzeit
                                      aenam = sy-uname
                            processing_time = utclong_current( ) ) ) ).

    lt_broken = VALUE ztt_allocation(
                 BASE lt_broken
                  FOR <noemployee> IN FILTER #( mt_allocation EXCEPT IN lt_broken
                                                              WHERE mandt = mandt AND batch_id = batch_id AND record_id = record_id  )
                                      USING KEY pernr WHERE ( pernr = CONV persno( 0 ) )
              ( VALUE #( BASE <noemployee> status = `2`
                                          message = 'N�o foi poss�vel determinar o funcion�rio'(001)
                                            aedat = sy-datum
                                            aezet = sy-uzeit
                                            aenam = sy-uname
                                  processing_time = utclong_current( ) ) ) ).

    lt_broken = VALUE ztt_allocation(
                 BASE lt_broken
                  FOR <noemployee> IN FILTER #( mt_allocation EXCEPT IN lt_broken
                                                              WHERE mandt = mandt AND batch_id = batch_id AND record_id = record_id  )
                                      USING KEY lstar WHERE ( lstar IS INITIAL )
              ( VALUE #( BASE <noemployee> status = `2`
                                          message = 'N�o foi poss�vel determinar o tipo de atividade'(002)
                                            aedat = sy-datum
                                            aezet = sy-uzeit
                                            aenam = sy-uname
                                  processing_time = utclong_current( ) ) ) ).

    lt_broken = VALUE ztt_allocation(
                 BASE lt_broken
                  FOR <noemployee> IN FILTER #( mt_allocation EXCEPT IN lt_broken
                                                              WHERE mandt = mandt AND batch_id = batch_id AND record_id = record_id  )
                                      USING KEY kostl WHERE ( kostl IS INITIAL )
              ( VALUE #( BASE <noemployee> status = `2`
                                          message = 'N�o foi poss�vel determinar o centro de custo emissor'(003)
                                            aedat = sy-datum
                                            aezet = sy-uzeit
                                            aenam = sy-uname
                                  processing_time = utclong_current( ) ) ) ).

    UPDATE zwfs_allocation FROM TABLE @lt_broken.

    mt_allocation = FILTER #( mt_allocation EXCEPT IN lt_broken WHERE mandt = mandt AND batch_id = batch_id AND record_id = record_id ).

    DATA(t2) = timer->get_runtime( ).
    MESSAGE i099 WITH |{ ( t2 - t1 ) / 1000 }| INTO dummy.
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

    MESSAGE i064 WITH |{ lines( lt_broken ) }| INTO dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->MIGRAR_DADOS_CO
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_MIGRA_CO                    TYPE        ZTT_ALLOCATION_STD_WITHOUT_KEY
* | [<-()] RESULT                         TYPE        ABAP_BOOL
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD migrar_dados_co.

    CHECK it_migra_co[] IS NOT INITIAL.

    DATA:
      rl_pernr TYPE RANGE OF catsdb-pernr,
      rl_belnr TYPE RANGE OF catsdb-belnr,
      rl_wdate TYPE RANGE OF catsdb-workdate.

    CONSTANTS lc_jobname TYPE tbtcjob-jobname VALUE 'ZAPONTAMENTO_HORAS'.

    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = 'Aguardando JOB de transfer�ncia p/controlling...'(011)
        i_output_immediately = abap_true ).


    LOOP AT it_migra_co ASSIGNING FIELD-SYMBOL(<migrar>).
      INSERT VALUE #( sign = 'I' option = 'EQ' low = <migrar>-pernr ) INTO TABLE rl_pernr.
      INSERT VALUE #( sign = 'I' option = 'EQ' low = <migrar>-belnr ) INTO TABLE rl_belnr.

      IF <migrar>-date_cats IS NOT INITIAL.
        INSERT VALUE #( sign = 'I' option = 'EQ' low = <migrar>-date_cats ) INTO TABLE rl_wdate.
      ELSE.
        SELECT SINGLE counter, workdate FROM catsdb WHERE counter = @<migrar>-counter INTO @DATA(castsdb).
        IF sy-subrc = 0.
          INSERT VALUE #( sign = 'I' option = 'EQ' low = castsdb-workdate ) INTO TABLE rl_wdate.
        ELSE.
          INSERT VALUE #( sign = 'I' option = 'EQ' low = <migrar>-zdate ) INTO TABLE rl_wdate.
        ENDIF.
      ENDIF.

      DATA(finished) = executar_job_migrar_co( EXPORTING it_pernr = rl_pernr[]
                                                         it_belnr = rl_belnr[]
                                                         it_wdate = rl_wdate[]
                                                         iv_count = sy-index ).

      CLEAR:
        rl_pernr,
        rl_belnr,
        rl_wdate.
    ENDLOOP.


    "Devido a limita��o do Range ABAP a espera pelo commit dos
    "registros tamb�m foi adaptada
*    esperar_transferencia_co( it_pernr = rl_pernr[] it_belnr = rl_belnr[] it_wdate = rl_wdate[] ).
    esperar_transferencia_co( it_migra_co = it_migra_co[] ).

    IF finished = abap_true.
      result = abap_true.
      LOOP AT it_migra_co ASSIGNING FIELD-SYMBOL(<migrar_co>).
        ASSIGN mt_allocation[ mandt = sy-mandt
                              batch_id = <migrar_co>-batch_id
                              record_id = <migrar_co>-record_id ]
            TO FIELD-SYMBOL(<migrado>).
        IF sy-subrc = 0.
          <migrado>-aedat = sy-datum.
          <migrado>-aezet = sy-uzeit.
          <migrado>-processing_time = utclong_current( ).
          IF <migrar>-date_cats IS NOT INITIAL.
            DATA(date) = <migrado>-date_cats.
          ELSE.
            SELECT SINGLE counter, workdate FROM catsdb WHERE counter = @<migrado>-counter INTO @DATA(castsdbx).
            IF sy-subrc = 0.
              date = castsdbx-workdate .
            ELSE.
              date = <migrado>-zdate.
            ENDIF.
          ENDIF.
          IF line_exists( mt_catsco[ KEY migrar pernr = <migrar_co>-pernr
                                             workdate = date
                                                belnr = <migrar_co>-belnr ] ).
            <migrado>-status = CONV #( success ).
            <migrado>-message = 'Apontamento e Migra��o CO realizados com sucesso'(008).
          ELSE.
            <migrado>-status = CONV #( migrar_co ).
            <migrado>-message = 'Erro ao migrar para CO'(007).
          ENDIF.
          UPDATE zwfs_allocation FROM <migrado>.
        ENDIF.
      ENDLOOP.
    ENDIF.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->CHAMAR_BAPI_PARA_APONTAR
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_CATSRECORDS                 TYPE        TT_BAPICATS1
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD chamar_bapi_para_apontar.

    MESSAGE i068 INTO DATA(dummy).
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    DATA(timer) = cl_abap_runtime=>create_hr_timer( ).
    DATA(t1) = timer->get_runtime( ).

    LOG-POINT ID zps20 FIELDS it_catsrecords .

    DATA catsrecords_out TYPE STANDARD TABLE OF bapicats2.
    DATA longtext TYPE STANDARD TABLE OF bapicats8.

    DO lines( it_catsrecords ) TIMES.

      cl_progress_indicator=>progress_indicate(
        EXPORTING
          i_text               = |{ dummy } { sy-index } / { lines( it_catsrecords ) }|
          i_processed          = sy-index
          i_total              = lines( it_catsrecords )
          i_output_immediately = abap_false ).

      DATA(catsrecords_in) = VALUE tt_bapicats1( FOR <catsrecord> IN it_catsrecords FROM sy-index TO sy-index ( <catsrecord> ) ).
      DATA(extensionin) = VALUE bapiparex_tab(
                            FOR <ext> IN catsrecords_in INDEX INTO _tabix
                          ( structure = 'BAPI_TE_CATSDB'
                           valuepart1 = VALUE bapi_te_catsdb(
                                          row = CONV #( _tabix )
                                     batch_id = <ext>-shorttext(10)
                                    record_id = <ext>-shorttext+10(10) ) ) ).

      MESSAGE i055 WITH catsrecords_in[ 1 ]-workdate
                        catsrecords_in[ 1 ]-employeenumber
                        COND #( WHEN catsrecords_in[ 1 ]-rec_order IS INITIAL
                                THEN catsrecords_in[ 1 ]-wbs_element
                                ELSE catsrecords_in[ 1 ]-rec_order )
                        catsrecords_in[ 1 ]-shorttext
                   INTO dummy.
      zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
      zcl_ptool_helper=>bal_db_save( ).

      CALL FUNCTION 'BAPI_CATIMESHEETMGR_INSERT'
        EXPORTING
          profile         = c_proj_name
          testrun         = _testrun
        TABLES
          catsrecords_in  = catsrecords_in
          catsrecords_out = catsrecords_out
          extensionin     = extensionin
          longtext        = longtext
          return          = mt_return.

      LOOP AT mt_return ASSIGNING FIELD-SYMBOL(<return>)
                        WHERE type <> `W`.
        MESSAGE ID <return>-id         ##NEEDED
           TYPE <return>-type
         NUMBER <return>-number
           WITH <return>-message_v1 <return>-message_v2 <return>-message_v3 <return>-message_v4
           INTO DATA(lv_dummy).
        zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
      ENDLOOP.
      zcl_ptool_helper=>bal_db_save( ).

      IF catsrecords_out IS NOT INITIAL.

        ASSIGN mt_allocation[ mandt = sy-mandt
                              batch_id = catsrecords_out[ 1 ]-shorttext(10)
                              record_id = catsrecords_out[ 1 ]-shorttext+10(10) ]
            TO FIELD-SYMBOL(<processado>).

        IF sy-subrc = 0.
*          IF <processado>-zdate = catsrecords_out[ 1 ]-workdate .
          <processado>-counter = catsrecords_out[ 1 ]-counter.
          <processado>-belnr = catsrecords_out[ 1 ]-cats_doc_no.
          <processado>-date_cats = catsrecords_out[ 1 ]-workdate.
          <processado>-status = CONV #( success ).
          <processado>-aedat = sy-datum.
          <processado>-aezet = sy-uzeit.
          <processado>-aenam = sy-uname.
          <processado>-processing_time = utclong_current( ).
          <processado>-message = 'Apontamento realizado com sucesso'(009).
          IF <processado>-type = 'PEP'.
            <processado>-status = CONV #( migrar_co ).
            INSERT VALUE #( BASE <processado> zdate = catsrecords_out[ 1 ]-workdate zhour = catsrecords_out[ 1 ]-catshours ) INTO TABLE mt_migra_co.
          ENDIF.
*          ENDIF.
          DATA(alloc) = CORRESPONDING zwfs_allocation( <processado> ).
          UPDATE zwfs_allocation FROM alloc.
        ENDIF.
        LOG-POINT ID zps20 FIELDS <processado>.

      ELSE.

        ASSIGN mt_allocation[ mandt = sy-mandt
                              batch_id = catsrecords_in[ 1 ]-shorttext(10)
                              record_id = catsrecords_in[ 1 ]-shorttext+10(10) ]
            TO FIELD-SYMBOL(<erro>).

        IF <erro>-zdate = catsrecords_in[ 1 ]-workdate .
          <erro>-status = CONV #( error ).
          <erro>-message = 'Ocorreu um erro no lan�amento, acessar SLG1 para mais detalhes'(005).
          <erro>-aedat = sy-datum.
          <erro>-aezet = sy-uzeit.
          <erro>-aenam = sy-uname.
          <erro>-processing_time = utclong_current( ).
          CLEAR alloc.
          alloc = CORRESPONDING zwfs_allocation( <erro> ).
          UPDATE zwfs_allocation FROM alloc.
        ENDIF.
        LOG-POINT ID zps20 FIELDS <erro>.

      ENDIF.

      LOG-POINT ID zps20 FIELDS catsrecords_out .

      CLEAR:
        catsrecords_out,
        extensionin,
        mt_return.

    ENDDO.

    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = abap_true.

    DATA(t2) = timer->get_runtime( ).
    MESSAGE i099 WITH |{ ( t2 - t1 ) / 1000 }| INTO dummy.
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

    MESSAGE i069 WITH |{ lines( it_catsrecords ) }| INTO dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->CHAMAR_BAPI_PARA_ELIMINAR
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_CATSRECORDS                 TYPE        CATS_ESA_DELETE_REC_T
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD chamar_bapi_para_eliminar.

    DATA lt_migrar TYPE ztt_allocation_without_key.
    DATA migrar_new TYPE STANDARD TABLE OF zst_allocation.

    MESSAGE i065 INTO DATA(dummy).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    DATA(timer) = cl_abap_runtime=>create_hr_timer( ).
    DATA(t1) = timer->get_runtime( ).

    LOG-POINT ID zps20 FIELDS it_catsrecords .

    DO lines( it_catsrecords ) TIMES.

      cl_progress_indicator=>progress_indicate(
        EXPORTING
          i_text               = |{ dummy } { sy-index } / { lines( it_catsrecords ) }|
          i_processed          = sy-index
          i_total              = lines( it_catsrecords )
          i_output_immediately = abap_false ).

      DATA(catsrecords) = VALUE cats_esa_delete_rec_t( FOR <catsrecord> IN it_catsrecords FROM sy-index TO sy-index ( <catsrecord> ) ).

      MESSAGE i056 WITH catsrecords[ 1 ]-counter INTO dummy.
      zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

      CALL FUNCTION 'BAPI_CATIMESHEETMGR_DELETE'
        EXPORTING
          profile      = c_proj_name
          testrun      = _testrun
          release_data = abap_true
        TABLES
          catsrecords  = catsrecords
          return       = mt_return.

      LOOP AT mt_return ASSIGNING FIELD-SYMBOL(<return>)
                        WHERE type <> `W`.

        MESSAGE ID <return>-id
           TYPE <return>-type
         NUMBER <return>-number
           WITH <return>-message_v1 <return>-message_v2 <return>-message_v3 <return>-message_v4
           INTO DATA(lv_dummy).
        zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

        IF ( <return>-type = `E` ).
          UPDATE zwfs_allocation SET  status = `2`
                                     message = lv_dummy
                               WHERE counter = <return>-message_v1.
        ENDIF.

      ENDLOOP.
      zcl_ptool_helper=>bal_db_save( ).

      IF NOT line_exists( mt_return[ type = 'E' ] ).
        DATA(lv_counter) = catsrecords[ 1 ]-counter.

        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait = abap_true.

        SELECT DISTINCT
               z~mandt, z~batch_id, z~record_id, z~employee_id, z~zdate,
               c~counter, c~belnr, z~pay_code, z~project_id, z~zhour, z~operation,
               z~erdat, z~erzet, z~ernam, z~aedat, z~aezet, z~aenam,
               utcl_current( ) AS register_time, utcl_current( ) AS processing_time,
               z~status, z~message,
               a~pernr, b~kostl, a~usrid, d~lstar, j~pspnr, j~profl,
               coalesce( p~posid_edit, k~aufnr ) AS objnr,
               coalesce( CASE WHEN p~posid_edit IS NOT NULL THEN 'PEP' END,
                         CASE WHEN k~aufnr IS NOT NULL THEN 'ORDEM' END )
                      AS type,
               @space AS locked,
               c~workdate
          FROM zwfs_allocation AS z
          LEFT JOIN pa0105 AS a ON   a~usrid = z~employee_id
                               AND   a~subty = '0002'
                               AND ( a~endda >= @sy-datum AND a~begda <= @sy-datum )
          LEFT JOIN pa0001 AS b ON   b~pernr = a~pernr
                               AND ( b~endda >= @sy-datum AND b~begda <= @sy-datum )
          LEFT JOIN pa0315 AS d ON   d~pernr = a~pernr
                               AND ( d~endda >= @sy-datum AND d~begda <= @sy-datum )
          LEFT JOIN prps   AS p ON p~posid_edit = z~project_id
          LEFT JOIN aufk   AS k ON k~aufnr = z~project_id
          LEFT JOIN proj   AS j ON j~pspnr = p~psphi
          JOIN catsdb          AS c ON c~batch_id = z~batch_id
                                   AND c~record_id = z~record_id
         WHERE ( c~counter = @lv_counter OR c~refcounter = @lv_counter )
          INTO TABLE @lt_migrar.

        DATA(lv_utclong) =  utclong_current( ).
        LOOP AT lt_migrar ASSIGNING FIELD-SYMBOL(<migrar>).

          UPDATE zwfs_allocation SET status = '4',
                                    message = @text-006,
                                      aedat = @sy-datum,
                                      aezet = @sy-uzeit,
                                      aenam = @sy-uname,
                            processing_time = @lv_utclong
                              WHERE record_id = @<migrar>-record_id
                                AND employee_id = @<migrar>-employee_id
                                AND operation = '1'.

          UPDATE zwfs_allocation SET status = '3',
                                    message = @text-006,
                                      aedat = @sy-datum,
                                      aezet = @sy-uzeit,
                                      aenam = @sy-uname,
                            processing_time = @lv_utclong
                              WHERE record_id = @<migrar>-record_id
                                AND employee_id = @<migrar>-employee_id
                                AND operation = '0'.

        ENDLOOP.

      ENDIF.

      mt_migra_co = VALUE #( BASE mt_migra_co ( LINES OF FILTER #( lt_migrar EXCEPT IN mt_migra_co WHERE mandt = mandt
                                                                                                     AND batch_id = batch_id
                                                                                                     AND record_id = record_id
                                                                                                     AND employee_id = employee_id
                                                                                                     AND counter = counter
                                                                                                     AND belnr = belnr ) ) ).


      CLEAR:
        catsrecords,
        mt_return.

    ENDDO.

    DATA(t2) = timer->get_runtime( ).
    MESSAGE i099 WITH |{ ( t2 - t1 ) / 1000 }| INTO dummy.
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

    MESSAGE i066 WITH |{ lines( it_catsrecords ) }| INTO dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->DESTRAVAR_APONTAMENTOS
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD destravar_apontamentos.
    CALL FUNCTION 'DEQUEUE_EZWFS_ALLOC'.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->ESPERAR_TRANSFERENCIA_CO
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_PERNR                       TYPE        TY_R_PERNR(optional)
* | [--->] IT_BELNR                       TYPE        TY_R_BELNR(optional)
* | [--->] IT_WDATE                       TYPE        TY_R_WDATE(optional)
* | [--->] IT_MIGRA_CO                    TYPE        ZTT_ALLOCATION_STD_WITHOUT_KEY(optional)
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD esperar_transferencia_co.

    DATA migra_co TYPE STANDARD TABLE OF zst_allocation.

    CHECK it_migra_co[] IS NOT INITIAL.

    GET TIME STAMP FIELD DATA(lv_time_ini).
    GET TIME STAMP FIELD DATA(lv_time_fim).
    ADD 60 TO lv_time_fim.

    migra_co = it_migra_co.

    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = abap_true.

    WHILE lv_time_ini <= lv_time_fim.
      GET TIME STAMP FIELD lv_time_ini.
      " Devido � limita��o do Range este select foi adaptado
      " para um JOIN ao inv�s de Ranges
*      SELECT DISTINCT
*             counter, stokz, pernr, workdate, catshours, belnr, transfer
*        FROM catsco
*       WHERE stokz = @abap_false
*         AND pernr IN @it_pernr[]
*         AND belnr IN @it_belnr[]
*         AND workdate IN @it_wdate[]
*        INTO TABLE @DATA(lt_catsco).
      SELECT DISTINCT
             c~counter, c~stokz, c~pernr, c~workdate, c~catshours, c~belnr, c~transfer
        FROM @migra_co AS i
        JOIN catsco AS c ON c~stokz = @abap_false
                        AND c~pernr = i~pernr
                        AND c~belnr = i~belnr
*                        AND c~workdate = i~zdate
        INTO TABLE @DATA(lt_catsco).

      IF sy-subrc = 0.
        EXIT.
      ENDIF.

    ENDWHILE.

    mt_catsco = VALUE #(
                 BASE mt_catsco
              ( LINES OF VALUE #(
                           FOR <catsco> IN FILTER #( lt_catsco EXCEPT IN mt_catsco
                                                                WHERE counter = counter ) ( <catsco> ) ) ) ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_APONTAMENTO_HORAS_NEW->SELECIONAR_APONTAMENTOS
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD selecionar_apontamentos.

    TYPES ty_r_status TYPE RANGE OF zwfs_status.

    MESSAGE i061 INTO DATA(dummy).
    LOG-POINT ID zps20 FIELDS dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).

    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    DATA(timer)  = cl_abap_runtime=>create_hr_timer( ).
    DATA(t1) = timer->get_runtime( ).

    IF r_status[] IS INITIAL.
      CASE _process_type.
        WHEN 'P'.
          r_status = VALUE ty_r_status(
                             sign = 'I'
                           option = 'EQ'
                            ( low = '0' ) ( low = '6' ) ).

        WHEN 'R'.
          r_status = VALUE ty_r_status(
                       sign = 'I'
                     option = 'EQ'
                      ( low = '2' ) ( low = '5' ) ( low = '6' ) ).

        WHEN OTHERS.
          r_status = VALUE ty_r_status(
                       sign = 'I'
                     option = 'EQ'
                      ( low = '0' ) ( low = '2' ) ( low = '5' ) ( low = '6' ) ).

      ENDCASE.
    ENDIF.

    SELECT DISTINCT
           z~mandt, z~batch_id, z~record_id, z~employee_id, z~zdate,
           z~counter, z~belnr, z~pay_code, z~project_id, z~zhour, z~operation,
           z~erdat, z~erzet, z~ernam, z~aedat, z~aezet, z~aenam,
           utcl_current( ) AS register_time, utcl_current( ) AS processing_time,
           z~status, z~message,
           a~pernr, b~kostl, a~usrid, c~lstar, j~pspnr, j~profl,
           coalesce( p~posid_edit, k~aufnr ) AS objnr,
           coalesce( CASE WHEN p~posid_edit IS NOT NULL THEN 'PEP' END,
                     CASE WHEN k~aufnr IS NOT NULL THEN 'ORDEM' END )
                  AS type,
           @space AS locked
      FROM zwfs_allocation AS z
      LEFT JOIN pa0105 AS a ON   a~usrid = z~employee_id
                           AND   a~subty = '0002'
                           AND ( a~endda >= @sy-datum AND a~begda <= @sy-datum )
      LEFT JOIN pa0001 AS b ON   b~pernr = a~pernr
                           AND ( b~endda >= @sy-datum AND b~begda <= @sy-datum )
      LEFT JOIN pa0315 AS c ON   c~pernr = a~pernr
                           AND ( c~endda >= @sy-datum AND c~begda <= @sy-datum )
      LEFT JOIN prps   AS p ON p~posid_edit = z~project_id
      LEFT JOIN aufk   AS k ON k~aufnr = z~project_id
      LEFT JOIN proj   AS j ON j~pspnr = p~psphi
     WHERE z~batch_id    IN @r_batch_id[]
       AND z~record_id   IN @r_record_id[]
       AND z~zdate       IN @r_zdate[]
       AND z~employee_id IN @r_employee_id[]
       AND z~project_id  IN @r_project_id[]
       AND z~erdat       IN @r_erdat[]
       AND z~aedat       IN @r_aedat[]
       AND z~pay_code    IN @r_pay_code[]
       AND z~status      IN @r_status[]
      INTO TABLE @mt_allocation.

    IF sy-subrc = 0.

      LOG-POINT ID zps20 FIELDS mt_allocation[].

      SELECT DISTINCT
             c~pernr, c~workdate, CAST( SUM( c~catshours ) AS QUAN( 15, 3 ) ) AS catshours
        FROM @mt_allocation AS i
        JOIN catsdb AS c ON c~pernr = i~pernr
                        AND c~workdate = concat( substring( i~zdate, 1, 6 ), '01' )
       GROUP BY c~pernr, c~workdate
        INTO TABLE @DATA(mt_workdates).


      SELECT DISTINCT
             e~*
        FROM @mt_allocation AS i
        JOIN zwfs_allocation AS e ON e~record_id = i~record_id
       WHERE i~operation = 1 "eliminar apontamento
         AND e~status = 3    "apontamentos com sucesso
        INTO TABLE @mt_apontados.

      SELECT DISTINCT
             c~*
        FROM @mt_allocation AS i
        JOIN catsdb AS c ON ( ( c~record_id = i~record_id )
                           OR ( c~ltxa1 = concat( i~batch_id, i~record_id )
                             OR c~ltxa1 = concat( i~batch_id, concat( '_', i~record_id ) ) ) )
                        AND c~status <> '60' "estornado
       WHERE i~operation = 0
        INTO TABLE @mt_catsdb.

    ENDIF.

    DATA(t2) = timer->get_runtime( ).
    MESSAGE i099 WITH |{ ( t2 - t1 ) / 1000 }| INTO dummy.
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

    MESSAGE i062 WITH |{ lines( mt_allocation ) }| INTO dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->TRAVAR_APONTAMENTOS
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD travar_apontamentos.

    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = 'Travando os apontamentos selecionados...'(010)
        i_output_immediately = abap_true ).

    LOOP AT mt_allocation ASSIGNING FIELD-SYMBOL(<alloc>).
      CALL FUNCTION 'ENQUEUE_EZWFS_ALLOC'
        EXPORTING
          mode_zwfs_allocation = 'E'
          mandt                = sy-mandt
          batch_id             = <alloc>-batch_id
          record_id            = <alloc>-record_id
          x_batch_id           = ' '
          x_record_id          = ' '
          _scope               = '2'
          _wait                = ' '
          _collect             = ' '
        EXCEPTIONS
          foreign_lock         = 1
          system_failure       = 2
          OTHERS               = 3.
      IF sy-subrc <> 0.
        CLEAR <alloc>-locked.
      ELSE.
        <alloc>-locked = abap_true.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_APONTAMENTO_HORAS_NEW->SET_MT_ALLOCATION
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_ALLOCATION                  TYPE        ZTT_ALLOCATION
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD set_mt_allocation.
    mt_zwfs_allocation = CORRESPONDING #( it_allocation ).
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_APONTAMENTO_HORAS_NEW->SET_FILTER
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_PROJECT_ID                  TYPE        TY_R_PROJECT_ID(optional)
* | [--->] IT_ZDATE                       TYPE        TY_R_ZDATE(optional)
* | [--->] IT_BATCH_ID                    TYPE        TY_R_BATCH_ID(optional)
* | [--->] IT_RECORD_ID                   TYPE        TY_R_RECORD_ID(optional)
* | [--->] IT_EMPLOYEE_ID                 TYPE        TY_R_EMPLOYEE_ID(optional)
* | [--->] IT_ERDAT                       TYPE        TY_R_ERDAT(optional)
* | [--->] IT_AEDAT                       TYPE        TY_R_AEDAT(optional)
* | [--->] IT_PAY_CODE                    TYPE        TY_R_PAY_CODE(optional)
* | [--->] IT_STATUS                      TYPE        TY_R_STATUS(optional)
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD set_filter.

    r_project_id = it_project_id[].
    r_zdate      = it_zdate[].
    r_batch_id  = it_batch_id[].
    r_record_id  = it_record_id[].
    r_employee_id = it_employee_id[].
    r_erdat      = it_erdat[].
    r_aedat      = it_aedat[].
    r_pay_code   = it_pay_code[].
    r_status     = it_status[].

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->SELECIONAR_WFS_ALLOCATION
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD selecionar_wfs_allocation.
    TYPES ty_r_status TYPE RANGE OF zwfs_status.

    MESSAGE i061 INTO DATA(dummy).
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).

    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    DATA(timer)  = cl_abap_runtime=>create_hr_timer( ).
    DATA(t1) = timer->get_runtime( ).

    CASE _process_type.
      WHEN `P`.
        DATA(rl_status) = VALUE ty_r_status(
                           sign = `I`
                         option = `EQ`
                          ( low = `0` ) ).

      WHEN `R`.
        rl_status = VALUE ty_r_status(
                     sign = `I`
                   option = `EQ`
                    ( low = `2` ) ( low = `5` ) ).

      WHEN OTHERS.
        rl_status = VALUE ty_r_status(
                     sign = `I`
                   option = `EQ`
                    ( low = `0` ) ( low = `2` ) ( low = `5` ) ).

    ENDCASE.

    SELECT DISTINCT
           *
      FROM zwfs_allocation
     WHERE status IN @rl_status
      INTO TABLE @mt_zwfs_allocation.

    DATA(t2) = timer->get_runtime( ).
    MESSAGE i099 WITH |{ ( t2 - t1 ) / 1000 }| INTO dummy.
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

    MESSAGE i062 WITH |{ lines( mt_allocation ) }| INTO dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_APONTAMENTO_HORAS_NEW->SELECIONAR_REPROCESSAMENTO
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_ALLOCATION                  TYPE        TY_T_ALLOCATION
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD selecionar_reprocessamento.

    MESSAGE i061 INTO DATA(dummy).
    LOG-POINT ID zps20 FIELDS dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).

    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    DATA(timer)  = cl_abap_runtime=>create_hr_timer( ).
    DATA(t1) = timer->get_runtime( ).

    SELECT DISTINCT
           z~*,
           a~pernr, b~kostl, a~usrid, c~lstar, j~pspnr, j~profl,
           coalesce( p~posid_edit, k~aufnr ) AS objnr,
           coalesce( CASE WHEN p~posid_edit IS NOT NULL THEN 'PEP' END,
                     CASE WHEN k~aufnr IS NOT NULL THEN 'ORDEM' END )
                  AS type,
           @space AS locked
      FROM @it_allocation AS i
      JOIN zwfs_allocation AS z ON ( z~batch_id = i~batch_id
                               AND   z~record_id = i~record_id )
      LEFT JOIN pa0105     AS a ON   a~usrid = z~employee_id
                               AND   a~subty = '0002'
                               AND ( a~endda >= @sy-datum AND a~begda <= @sy-datum )
      LEFT JOIN pa0001     AS b ON   b~pernr = a~pernr
                               AND ( b~endda >= @sy-datum AND b~begda <= @sy-datum )
      LEFT JOIN pa0315     AS c ON   c~pernr = a~pernr
                               AND ( c~endda >= @sy-datum AND c~begda <= @sy-datum )
      LEFT JOIN prps       AS p ON p~posid_edit = z~project_id
      LEFT JOIN aufk       AS k ON k~aufnr = z~project_id
      LEFT JOIN proj       AS j ON j~pspnr = p~psphi
     WHERE z~batch_id    IN @r_batch_id[]
       AND z~record_id   IN @r_record_id[]
       AND z~zdate       IN @r_zdate[]
       AND z~employee_id IN @r_employee_id[]
       AND z~project_id  IN @r_project_id[]
       AND z~erdat       IN @r_erdat[]
       AND z~aedat       IN @r_aedat[]
       AND z~pay_code    IN @r_pay_code[]
       AND z~status      IN @r_status[]
      INTO TABLE @mt_allocation.

    IF sy-subrc = 0.

      LOG-POINT ID zps20 FIELDS mt_allocation[].

      SELECT DISTINCT
             c~pernr, c~workdate, CAST( SUM( c~catshours ) AS QUAN( 15, 3 ) ) AS catshours
        FROM @mt_allocation AS i
        JOIN catsdb AS c ON c~pernr = i~pernr
                        AND c~workdate = concat( substring( i~zdate, 1, 6 ), '01' )
       GROUP BY c~pernr, c~workdate
        INTO TABLE @DATA(mt_workdates).

      SELECT DISTINCT
             e~*
        FROM @mt_allocation AS i
        JOIN zwfs_allocation AS e ON e~record_id = i~record_id
       WHERE i~operation = 1 "criar apontamento
         AND e~status = 3    "apontamentos com sucesso
        INTO TABLE @mt_apontados.

      SELECT DISTINCT
             c~*
        FROM @mt_allocation AS i
        JOIN catsdb AS c ON ( ( c~record_id = i~record_id )
                           OR ( c~ltxa1 = concat( i~batch_id, i~record_id )
                             OR c~ltxa1 = concat( i~batch_id, concat( '_', i~record_id ) ) ) )
                        AND c~status <> '60' "estornado
        INTO TABLE @mt_catsdb.

    ENDIF.

    DATA(t2) = timer->get_runtime( ).
    MESSAGE i099 WITH |{ ( t2 - t1 ) / 1000 }| INTO dummy.
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

    MESSAGE i062 WITH |{ lines( mt_allocation ) }| INTO dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_APONTAMENTO_HORAS_NEW->REPROCESSAR
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_ALLOCATION                  TYPE        TY_T_ALLOCATION
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD reprocessar.

    MESSAGE i072 INTO DATA(dummy).
    LOG-POINT ID zps20 FIELDS dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

    DATA(timer) = cl_abap_runtime=>create_hr_timer( ).
    DATA(t1) = timer->get_runtime( ).

* Ler apontamentos para processar
    selecionar_reprocessamento( it_allocation ).

* Trava os registros para evitar conflitos
    travar_apontamentos( ).

* Elimina registros inv�lidos do processamento e grava log
    limpar_dados( ).

* Elimina registros nulos
    eliminar_apontamentos( ).

* Cria apontamentos
    apontar( ).

* Busca projeto e migra dados CO
    buscar_projetos( ).

* Destrava os registros
    destravar_apontamentos( ).

    DATA(t2) = timer->get_runtime( ).
    MESSAGE i099 WITH |{ ( t2 - t1 ) / 1000 }| INTO dummy.
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).

    MESSAGE i073 INTO dummy.
    cl_progress_indicator=>progress_indicate(
      EXPORTING
        i_text               = dummy
        i_output_immediately = abap_true ).
    zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    zcl_ptool_helper=>bal_db_save( ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_APONTAMENTO_HORAS_NEW->REDEFINIR
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_ALLOCATION                  TYPE        ZTT_ALLOCATION
* | [--->] IV_STATUS                      TYPE        ZWFS_STATUS
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD redefinir.

    LOOP AT it_allocation ASSIGNING FIELD-SYMBOL(<alloc>).
      CASE iv_status.
        WHEN 0.
          UPDATE zwfs_allocation
             SET status = iv_status
                 aedat = sy-datum
                 aenam = sy-uname
                 aezet = sy-uzeit
                 belnr = abap_false
                 counter = abap_false
                 processing_time = utclong``
                 message = abap_false
           WHERE batch_id = <alloc>-batch_id
             AND record_id = <alloc>-record_id.
        WHEN 1.
          UPDATE zwfs_allocation
             SET status = iv_status
                 aedat = sy-datum
                 aenam = sy-uname
                 aezet = sy-uzeit
                 belnr = abap_false
                 counter = abap_false
                 processing_time = utclong``
                 message = abap_false
           WHERE batch_id = <alloc>-batch_id
             AND record_id = <alloc>-record_id.
        WHEN 2.
          UPDATE zwfs_allocation
             SET status = iv_status
           WHERE batch_id = <alloc>-batch_id
             AND record_id = <alloc>-record_id.
        WHEN 3.
          UPDATE zwfs_allocation
             SET status = iv_status
           WHERE batch_id = <alloc>-batch_id
             AND record_id = <alloc>-record_id.
        WHEN 4.
          UPDATE zwfs_allocation
             SET status = iv_status
           WHERE batch_id = <alloc>-batch_id
             AND record_id = <alloc>-record_id.
        WHEN 5.
          UPDATE zwfs_allocation
             SET status = iv_status
           WHERE batch_id = <alloc>-batch_id
             AND record_id = <alloc>-record_id.
      ENDCASE.
    ENDLOOP.
    COMMIT WORK.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_APONTAMENTO_HORAS_NEW->GET_DATA
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RT_ALLOC                       TYPE        ZTT_ALLOCATION
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD get_data.
    rt_alloc = mt_allocation[].
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_APONTAMENTO_HORAS_NEW=>FACTORY
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RO_ALLOCATION                  TYPE REF TO ZCL_APONTAMENTO_HORAS_NEW
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD factory.
    ro_allocation = NEW zcl_apontamento_horas_new( ).
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_APONTAMENTO_HORAS_NEW->EXECUTAR_JOB_MIGRAR_CO
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_PERNR                       TYPE        TY_R_PERNR(optional)
* | [--->] IT_BELNR                       TYPE        TY_R_BELNR(optional)
* | [--->] IT_WDATE                       TYPE        TY_R_WDATE(optional)
* | [--->] IV_COUNT                       TYPE        I
* | [<-()] RV_FINISHED                    TYPE        ABAP_BOOL
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD executar_job_migrar_co.

    DATA:
      lv_jobcount TYPE tbtcjob-jobcount,
      aborted     TYPE c.

    CONSTANTS lc_jobname TYPE tbtcjob-jobname VALUE 'ZAPONTAMENTO_HORAS'.

    DATA(lv_jobname) = CONV tbtcjob-jobname( |{ lc_jobname }_{ iv_count }| ).
    LOG-POINT ID zps20 FIELDS it_pernr[] it_belnr[] it_wdate[] lv_jobname.

    CALL FUNCTION 'JOB_OPEN'
      EXPORTING
        jobname          = lv_jobname
      IMPORTING
        jobcount         = lv_jobcount
      EXCEPTIONS
        cant_create_job  = 1
        invalid_job_data = 2
        jobname_missing  = 3
        OTHERS           = 4.

    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid               ##NEEDED
         TYPE sy-msgty
       NUMBER sy-msgno
         WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
         INTO DATA(lv_dummy).
      zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    ENDIF.

    SUBMIT rcatstco WITH p_pernr IN it_pernr[]
                    WITH p_belnr IN it_belnr[]
                    WITH p_date  IN it_wdate[]
                    WITH p_test  = _testrun
                    WITH p_warn  = abap_true
                    USER sy-uname
                    VIA JOB lv_jobname
                    NUMBER lv_jobcount
                    AND RETURN.

    CALL FUNCTION 'JOB_CLOSE'
      EXPORTING
        jobcount             = lv_jobcount
        jobname              = lv_jobname
        strtimmed            = 'X'
      EXCEPTIONS
        cant_start_immediate = 1
        invalid_startdate    = 2
        jobname_missing      = 3
        job_close_failed     = 4
        job_nosteps          = 5
        job_notex            = 6
        lock_failed          = 7
        OTHERS               = 8.

    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid
         TYPE sy-msgty
       NUMBER sy-msgno
         WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
         INTO lv_dummy.
      zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
    ENDIF.

    GET TIME STAMP FIELD DATA(lv_time_ini).
    GET TIME STAMP FIELD DATA(lv_time_fim).
    ADD 30 TO lv_time_fim.

    WHILE lv_time_ini <= lv_time_fim.

      GET TIME STAMP FIELD lv_time_ini.

      CALL FUNCTION 'SHOW_JOBSTATE'
        EXPORTING
          jobcount         = lv_jobcount
          jobname          = lv_jobname
        IMPORTING
          aborted          = aborted
          finished         = rv_finished
        EXCEPTIONS
          jobcount_missing = 1
          jobname_missing  = 2
          job_notex        = 3
          OTHERS           = 4.

      IF sy-subrc <> 0.
        MESSAGE ID sy-msgid
           TYPE sy-msgty
         NUMBER sy-msgno
           WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
           INTO lv_dummy.
        zcl_ptool_helper=>bal_log_msg_add( iv_handle = _handle ).
      ENDIF.

      IF aborted = abap_true OR rv_finished = abap_true.
        LOG-POINT ID zps20 FIELDS aborted rv_finished.
        EXIT.
      ENDIF.

    ENDWHILE.

  ENDMETHOD.
ENDCLASS.