Sap PS Prog Adjustposid
Sap PS Prog Adjustposid
  begin of t_dataset,
    ver type ps_version_number,
    int type ps_number_intern,
    ext type ps_number_extern,
  end of t_dataset,
  begin of t_stat_msg,
    icon like icon-id,
    message type t_msg,
  end of t_stat_msg.
*---------------------------------------------------------------------*
* CLASS edmask_base DEFINITION
*   abstract base class - can analyse and fix mismatches between
*   database and edit mask
*
*   implement update_db, fetch_data, check_db, get_classid for
*   concrete implementations
*---------------------------------------------------------------------*
class edmask_base definition abstract.
  public section.
    data:
      checkmasks type tcjed-proid,
      lt_problem_masks type table of ps_edmask,
        squeezemode type c,
        testmode type c,
        dialogmode type c,
        lv_errorflag type c,
        lv_lasterror type t_msg.
      methods:
        constructor,
        limit importing mask type tcjed-proid,
        work,
        headline abstract,
        add_diag importing newmsg type t_msg
                           msgtype type i,
        show_diag,
        show_error.
    protected section.
      data:
        con_green type icon-id,
        con_yellow type icon-id,
        con_red type icon-id,
      methods:
        fix importing object          type t_dataset
                      new_external_id type ps_number_extern
            exporting rcode           type sy-subrc,
*---------------------------------------------------------------------*
* CLASS edmask_pdef DEFINITION
*---------------------------------------------------------------------*
class edmask_pdef definition inheriting from edmask_base.
  public section.
    methods:
      headline redefinition.
  protected section.
    methods:
      get_classid redefinition,
      check_db redefinition,
      fetch_data redefinition,
      update_db redefinition.
endclass.
*---------------------------------------------------------------------*
* CLASS edmask_wbs DEFINITION
*---------------------------------------------------------------------*
class edmask_wbs definition inheriting from edmask_base.
  public section.
    methods:
      headline redefinition.
  protected section.
    methods:
      get_classid redefinition,
      check_db redefinition,
      fetch_data redefinition,
      update_db redefinition.
endclass.
*---------------------------------------------------------------------*
* CLASS edmask_spdef DEFINITION
*---------------------------------------------------------------------*
class edmask_spdef definition inheriting from edmask_base.
  public section.
    methods:
      headline redefinition.
  protected section.
    methods:
      get_classid redefinition,
      check_db redefinition,
      fetch_data redefinition,
      update_db redefinition.
endclass.
*---------------------------------------------------------------------*
* CLASS edmask_std_wbs DEFINITION
*---------------------------------------------------------------------*
class edmask_std_wbs definition inheriting from edmask_base.
  public section.
    methods:
      headline redefinition.
  protected section.
    methods:
      get_classid redefinition,
      check_db redefinition,
      fetch_data redefinition,
      update_db redefinition.
endclass.
*---------------------------------------------------------------------*
* CLASS edmask_sim_pdef DEFINITION
*---------------------------------------------------------------------*
class edmask_sim_pdef definition inheriting from edmask_base.
  public section.
    methods:
      headline redefinition.
  protected section.
    methods:
      get_classid redefinition,
      check_db redefinition,
      fetch_data redefinition,
      update_db redefinition.
endclass.
*---------------------------------------------------------------------*
* CLASS edmask_sim_wbs DEFINITION
*---------------------------------------------------------------------*
class edmask_sim_wbs definition inheriting from edmask_base.
  public section.
    methods:
      headline redefinition.
  protected section.
    methods:
      get_classid redefinition,
      check_db redefinition,
      fetch_data redefinition,
      update_db redefinition.
endclass.
*---------------------------------------------------------------------*
* CLASS edmask_base IMPLEMENTATION
*---------------------------------------------------------------------*
class edmask_base implementation.
*---------------------------------------------------------------------*
* CONSTRUCTOR edmask_base
*---------------------------------------------------------------------*
  method constructor.
*   fetch icons
    select single id from icon into con_green
      where name = 'ICON_LED_GREEN'.
    select single id from icon into con_yellow
      where name = 'ICON_LED_YELLOW'.
    select single id from icon into con_red
      where name = 'ICON_LED_RED'.
      if lt_tcjed[] is initial.
        call method set_error exporting errormsg = 'No edit masks found.'.
        exit.
      endif.
    endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_base.squeeze
*---------------------------------------------------------------------*
* put external into edit mask, no matter what
*---------------------------------------------------------------------*
  method squeeze.
    constants:
      con_char(26) type c value 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
      con_num(10) type c value '0123456789'.
    data:
      lv_rcode type i,
      lv_id_pos type i,
      lv_mask_pos type i,
      lv_output type ps_number_extern,
      lv_id type ps_number_extern,
      lv_len type i,
      lv_masklen type i,
      lv_current_mask type c,
      lv_current_id type c.
      lv_output = mask-proid.
      lv_mask_pos = 0.
*       NUMBER
        if con_num ca lv_current_id.
          while lv_current_mask ne 'X' and lv_current_mask ne '0'.
             concatenate lv_output lv_current_mask into lv_output.
             add 1 to lv_mask_pos.
             if not lv_mask_pos < lv_masklen. exit. endif.
             lv_current_mask = mask-posid+lv_mask_pos(1).
          endwhile.
          if lv_current_mask eq 'X' or lv_current_mask eq '0'.
             concatenate lv_output lv_current_id into lv_output.
             add 1 to lv_mask_pos.
             if not lv_mask_pos < lv_masklen. lv_rcode = 1. endif.
          else.
             lv_rcode = 1.
          endif.
*       CHAR
        elseif con_char ca lv_current_id.
          while lv_current_mask ne 'X'.
             concatenate lv_output lv_current_mask into lv_output.
             add 1 to lv_mask_pos.
             if not lv_mask_pos < lv_masklen. exit. endif.
             lv_current_mask = mask-posid+lv_mask_pos(1).
          endwhile.
          if lv_current_mask eq 'X'.
             concatenate lv_output lv_current_id into lv_output.
             add 1 to lv_mask_pos.
             if not lv_mask_pos <= lv_masklen. lv_rcode = 1. endif.
          else.
             lv_rcode = 1.
          endif.
        endif.
        check lv_rcode is initial.
        add 1 to lv_id_pos.
      enddo.
      result = lv_output.
      rcode = lv_rcode.
*---------------------------------------------------------------------*
* METHOD edmask_base.limit
*---------------------------------------------------------------------*
* limit work to some edit masks
*---------------------------------------------------------------------*
  method limit.
*   fetch edit masks
    select * from tcjed into table lt_tcjed where proid = mask.
    if lt_tcjed[] is initial.
      call method set_error exporting errormsg = 'No edit masks found.'.
      exit.
    endif.
  endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_base.show_error
*---------------------------------------------------------------------*
* print out last error message
*---------------------------------------------------------------------*
  method show_error.
    if lv_errorflag is initial. exit. endif.
    format color col_negative.
    write: lv_lasterror.
  endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_base.show_diag
*---------------------------------------------------------------------*
* show diagnostic messags
*---------------------------------------------------------------------*
  method show_diag.
    field-symbols: <fs_msg> type t_stat_msg.
    loop at lt_diag assigning <fs_msg>.
      write: / <fs_msg>-icon as icon , <fs_msg>-message.
    endloop.
  endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_base.set_error
*---------------------------------------------------------------------*
* set internal error message+flag
*---------------------------------------------------------------------*
  method set_error.
    lv_errorflag = 'X'.
    lv_lasterror = errormsg.
  endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_base.add diag
*---------------------------------------------------------------------*
* add diag message
*---------------------------------------------------------------------*
  method add_diag.
    data:
      newbie type t_stat_msg.
    newbie-message = newmsg.
    if msgtype = 0.
      newbie-icon = con_green.
    elseif msgtype = 1.
      newbie-icon = con_yellow.
    elseif msgtype = 2.
      newbie-icon = con_red.
    endif.
*---------------------------------------------------------------------*
* METHOD get_valid_number
*---------------------------------------------------------------------*
* get a pspid from the user
*---------------------------------------------------------------------*
  method get_valid_number.
    data:
      lv_dummy type proj-pspid,
      lv_ext type ps_number_extern,
      lv_ext_user type ps_number_extern,
      lv_rcode type sy-subrc,
      lv_editmask(50) type c,
      lv_answerstring type spop-varvalue1,
      lv_answer type c,
      lv_exit type c,
      lv_helpstring(50) type c,
      lv_classid type t_msg.
        if lv_answer eq 'A'.
*         Cancel: skip this one
          lv_exit = 'X'.
          rval = 1.
        elseif not lv_answerstring is initial.
*       check wether user gave us valid input
          lv_ext_user = lv_answerstring(24).
          call method isvalid exporting external_id = lv_ext_user
                              importing output      = lv_ext
                                        rcode       = lv_rcode.
*---------------------------------------------------------------------*
* METHOD edmask_base.fix
*---------------------------------------------------------------------*
* try to rename object on database
* return 0 if renamed
*         1 if not renamed because we're in testmode
*         2 if not renamed due to db error
*         3 if not renamed because new entry exists
*---------------------------------------------------------------------*
  method fix.
    data:
      lv_rcode type sy-subrc.
*---------------------------------------------------------------------*
* METHOD edmask_base.work
*---------------------------------------------------------------------*
* do the actual work
*---------------------------------------------------------------------*
  method work.
    field-symbols:
      <fs_data> type t_dataset,
      <fs_tcjed> type ps_edmask.
    data:
      lv_msg type t_msg,
      lv_msg_type type i,
      lv_rcode type sy-subrc,
      lv_helpstring(50) type c,
      lv_ext type ps_number_extern,
      lv_first_error type c.
      clear lv_first_error.
      loop at lt_data assigning <fs_data>.
        add 1 to datasets.
        clear: lv_ext, lv_rcode.
    concatenate <fs_data>-ext
      'does not match' <fs_tcjed>-proid <fs_tcjed>-posid
      into lv_msg separated by space.
        if lv_rcode is initial.
          call method fix
            exporting object          = <fs_data>
                      new_external_id = lv_ext
            importing rcode           = lv_rcode.
          case lv_rcode.
            when 0.
              concatenate lv_msg 'renamed to' <fs_data>-ext
              into lv_msg separated by space.
              lv_msg_type = 0.
            when 1.
              concatenate lv_msg 'renaming possible to'
              <fs_data>-ext into lv_msg separated by space.
              lv_msg_type = 1.
              lv_rcode = 0.
                 when 2.
                    concatenate lv_msg 'database error renaming to'
                    <fs_data>-ext into lv_msg separated by space.
                    lv_msg_type = 2.
                 when 3.
                   concatenate lv_msg 'renamed entry already exists'
                   <fs_data>-ext into lv_msg separated by space.
                   lv_msg_type = 2.
              endcase.
            endif.
          endif.
*         DIALOG adjust
          if not lv_rcode is initial.
            add 1 to dialogcount.
            if testmode is initial and not dialogmode is initial.
              call method get_valid_number
              exporting
                wrongid = <fs_data>-ext
                version = <fs_data>-ver
                editmask = <fs_tcjed>
              importing
                newid = lv_ext
                rval = lv_rcode.
              if lv_rcode = 0.
                concatenate lv_msg ', new id is ' lv_ext into lv_msg
                  separated by space.
                call method update_db
                  exporting internal_id = <fs_data>-int
                            version     = <fs_data>-ver
                            new_external_id = lv_ext
                  importing rval = lv_rcode.
                 lv_msg_type = lv_rcode.
                 if lv_rcode = 2.
                    concatenate lv_msg 'database error' into lv_msg
                    separated by space.
                 endif.
               else.
                 concatenate lv_msg ', dialog aborted' into lv_msg
                    separated by space.
                 lv_msg_type = 2.
               endif.
             else.
*            unediting was not possible
               concatenate lv_msg
                 'dialog neccessary'
                 into lv_msg separated by space.
             endif.
          endif.
        endif.
        call method add_diag exporting newmsg = lv_msg
                                         msgtype = lv_msg_type.
      else.
        add 1 to okcount.
      endif.
    endloop.
    endloop.
  endmethod.
endclass. " edmask base
*---------------------------------------------------------------------*
*       CLASS edmask_pdef IMPLEMENTATION
*---------------------------------------------------------------------*
class edmask_pdef implementation.
  method headline.
    write: / 'project definition'.
  endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_pdef.update_db
*---------------------------------------------------------------------*
*   update PROJ if NOT in testmode
*---------------------------------------------------------------------*
  method update_db.
    data:
      newid type proj-pspid,
      oldid type proj-pspnr.
    if testmode is initial.
      newid = new_external_id.
      oldid = internal_id.
*---------------------------------------------------------------------*
* METHOD edmask_pdef.fetch_data
*---------------------------------------------------------------------*
*   select from proj into lt_data
*---------------------------------------------------------------------*
  method fetch_data.
    data:
      wa_proj type proj,
      ls_data type t_dataset,
      lv_searchstring(24) type c.
clear: lt_data.
      ls_data-int = wa_proj-pspnr.
      ls_data-ext = wa_proj-pspid.
      append ls_data to lt_data.
    endselect.
  endmethod.
**---------------------------------------------------------------------*
*---------------------------------------------------------------------*
* METHOD edmask_pdef.check_db
*---------------------------------------------------------------------*
*   check database for existing entries
*---------------------------------------------------------------------*
  method check_db.
    data:
      lv_dummy type projs-pspid.
    select single pspid from proj into lv_dummy
      where pspid = external_id.
    if sy-subrc is initial. rval = 1.
    else.                   rval = 0. endif.
  endmethod.
  method get_classid.
    classid = 'Project definition'.
  endmethod.
endclass. " edmask_pdef
*---------------------------------------------------------------------*
*       CLASS edmask_sim_pdef IMPLEMENTATION
*---------------------------------------------------------------------*
class edmask_sim_pdef implementation.
  method headline.
    write: / 'project definition of simulation/version'.
  endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_sim_pdef.update_db
*---------------------------------------------------------------------*
*   update VSPROJ_CN if NOT in testmode
*---------------------------------------------------------------------*
  method update_db.
    data:
      newid type vsproj_cn-pspid,
      oldid type vsproj_cn-pspnr.
    if testmode is initial.
      newid = new_external_id.
      oldid = internal_id.
*---------------------------------------------------------------------*
* METHOD edmask_sim_pdef.fetch_data
*---------------------------------------------------------------------*
*   select from vsproj_cn into lt_data
*---------------------------------------------------------------------*
  method fetch_data.
    data:
      wa_vsproj type vsproj_cn,
      ls_data type t_dataset,
      lv_searchstring(24) type c.
clear: lt_data.
      ls_data-ver = wa_vsproj-vsnmr.
      ls_data-int = wa_vsproj-pspnr.
      ls_data-ext = wa_vsproj-pspid.
      append ls_data to lt_data.
    endselect.
  endmethod.
*---------------------------------------------------------------------*
*---------------------------------------------------------------------*
* METHOD edmask_sim_pdef.check_db
*---------------------------------------------------------------------*
*   check database for existing entries
*---------------------------------------------------------------------*
  method check_db.
    data:
      lv_dummy type vsproj_cn.
    select single pspid from vsproj_cn into lv_dummy
      where pspid = external_id and vsnmr = version.
    if sy-subrc is initial. rval = 1.
    else.                   rval = 0. endif.
  endmethod.
  method get_classid.
    classid = 'Simulation project definition'.
  endmethod.
endclass. " edmask_sim_pdef
*---------------------------------------------------------------------*
*       CLASS edmask_spdef IMPLEMENTATION
*---------------------------------------------------------------------*
class edmask_spdef implementation.
  method headline.
    write: / 'standard project definition'.
  endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_spdef.update_db
*---------------------------------------------------------------------*
*   update PROJS if NOT in testmode
*---------------------------------------------------------------------*
  method update_db.
    data:
      newid type projs-pspid,
      oldid type projs-pspnr.
    if testmode is initial.
      newid = new_external_id.
      oldid = internal_id.
*---------------------------------------------------------------------*
* METHOD edmask_spdef.fetch_data
*---------------------------------------------------------------------*
*   select from projs into lt_data
*---------------------------------------------------------------------*
  method fetch_data.
    data:
      wa_projs type projs,
      ls_data type t_dataset,
      lv_searchstring(24) type c.
clear: lt_data.
      ls_data-int = wa_projs-pspnr.
      ls_data-ext = wa_projs-pspid.
      append ls_data to lt_data.
    endselect.
  endmethod.
*---------------------------------------------------------------------*
*---------------------------------------------------------------------*
* METHOD edmask_spdef.check_db
*---------------------------------------------------------------------*
*   check database for existing entries
*---------------------------------------------------------------------*
  method check_db.
    data:
      lv_dummy type projs-pspid.
    select single pspid from projs into lv_dummy
      where pspid = external_id.
    if sy-subrc is initial. rval = 1.
    else.                   rval = 0. endif.
  endmethod.
  method get_classid.
    classid = 'Standard project definition'.
  endmethod.
endclass. " edmask_sim_pdef
*---------------------------------------------------------------------*
*       CLASS edmask_wbs IMPLEMENTATION
*---------------------------------------------------------------------*
class edmask_wbs implementation.
*---------------------------------------------------------------------*
* METHOD edmask_wbs.update_db
*---------------------------------------------------------------------*
*   update PRPS if NOT in testmode
*---------------------------------------------------------------------*
  method update_db.
    data:
      newid type prps-posid,
      oldid type prps-pspnr.
    if testmode is initial.
      newid = new_external_id.
      oldid = internal_id.
*---------------------------------------------------------------------*
* METHOD edmask_wbs.fetch_data
*---------------------------------------------------------------------*
*   select from prps into lt_data
*---------------------------------------------------------------------*
  method fetch_data.
    data:
      wa_prps type prps,
      ls_data type t_dataset,
      lv_searchstring(24) type c.
clear: lt_data.
      ls_data-int = wa_prps-pspnr.
      ls_data-ext = wa_prps-posid.
      append ls_data to lt_data.
    endselect.
  endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_wbs.check_db
*---------------------------------------------------------------------*
*   check database for existing entries
*     return: 0 if free (entry does not exist), 1 otherwise
*---------------------------------------------------------------------*
  method check_db.
    data:
      lv_dummy type prps-posid.
    select single posid from prps into lv_dummy
      where posid = external_id.
    if sy-subrc is initial. rval = 1.
    else.                   rval = 0. endif.
  endmethod.
  method get_classid.
    classid = 'WBS-Element'.
  endmethod.
  method headline.
    write: / 'wbs element'.
  endmethod.
endclass. " edmask_wbs
*---------------------------------------------------------------------*
*       CLASS edmask_std_wbs IMPLEMENTATION
*---------------------------------------------------------------------*
class edmask_std_wbs implementation.
*---------------------------------------------------------------------*
* METHOD edmask_std_wbs.update_db
*---------------------------------------------------------------------*
*   update PRPSS if NOT in testmode
*---------------------------------------------------------------------*
  method update_db.
    data:
      newid type prpss-posid,
      oldid type prpss-pspnr.
    if testmode is initial.
      newid = new_external_id.
      oldid = internal_id.
*---------------------------------------------------------------------*
* METHOD edmask_std_wbs.fetch_data
*---------------------------------------------------------------------*
*   select from prpss into lt_data
*---------------------------------------------------------------------*
  method fetch_data.
    data:
      wa_prpss type prpss,
      ls_data type t_dataset,
      lv_searchstring(24) type c.
clear: lt_data.
      ls_data-int = wa_prpss-pspnr.
      ls_data-ext = wa_prpss-posid.
      append ls_data to lt_data.
    endselect.
  endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_wbs.check_db
*---------------------------------------------------------------------*
*   check database for existing entries
*     return: 0 if free (entry does not exist), 1 otherwise
*---------------------------------------------------------------------*
  method check_db.
    data:
      lv_dummy type prpss-posid.
    select single posid from prpss into lv_dummy
      where posid = external_id.
    if sy-subrc is initial. rval = 1.
    else.                    rval = 0. endif.
  endmethod.
    method get_classid.
      classid = 'Standard WBS-Element'.
    endmethod.
  method headline.
    write: / 'standard wbs element'.
  endmethod.
endclass. " edmask_std_wbs
*---------------------------------------------------------------------*
*       CLASS edmask_sim_wbs IMPLEMENTATION
*---------------------------------------------------------------------*
class edmask_sim_wbs implementation.
*---------------------------------------------------------------------*
* METHOD edmask_sim_wbs.update_db
*---------------------------------------------------------------------*
*   update VSPRPS_CN if NOT in testmode
*---------------------------------------------------------------------*
  method update_db.
    data:
      newid type vsprps_cn-posid,
      oldid type vsprps_cn-pspnr.
      if testmode is initial.
        newid = new_external_id.
        oldid = internal_id.
*---------------------------------------------------------------------*
* METHOD edmask_sim_wbs.fetch_data
*---------------------------------------------------------------------*
*   select from vsprps_cn into lt_data
*---------------------------------------------------------------------*
  method fetch_data.
    data:
      wa_vsprps type vsprps_cn,
      ls_data type t_dataset,
      lv_searchstring(24) type c.
clear: lt_data.
      ls_data-ver = wa_vsprps-vsnmr.
      ls_data-int = wa_vsprps-pspnr.
      ls_data-ext = wa_vsprps-posid.
      append ls_data to lt_data.
    endselect.
  endmethod.
*---------------------------------------------------------------------*
* METHOD edmask_sim_wbs.check_db
*---------------------------------------------------------------------*
*   check database for existing entries
*     return: 0 if free (entry does not exist), 1 otherwise
*---------------------------------------------------------------------*
  method check_db.
    data:
      lv_dummy type vsprps_cn-posid.
    select single posid from vsprps_cn into lv_dummy
      where posid = external_id and vsnmr = version.
    if sy-subrc is initial. rval = 1.
    else.                   rval = 0. endif.
  endmethod.
  method get_classid.
    classid = 'SIM-WBS-Element'.
  endmethod.
  method headline.
    write: / 'wbs element of project version/simulation'.
  endmethod.
endclass. " edmask_sim_wbs
*---------------------------------------------------------------------*
* INITIALIZATION
*---------------------------------------------------------------------*
initialization.
  tables: tcjed.
  data:
    gt_problem_masks type table of tcjed,
    gr_check type ref to edmask_base.
  field-symbols:
    <fs_tcjed> type tcjed.
* ---------------------------------------------------------------------
start-of-selection.
perform show_problems.
*---------------------------------------------------------------------*
* end
*---------------------------------------------------------------------*
*---------------------------------------------------------------------*
* show all edit masks w/ problems
*---------------------------------------------------------------------*
form show_problems.
  field-symbols:
    <fs_tcjed> type tcjed.
  data:
    lv_dummy(30) type c,
    wa_tcjet type tcjet.
      if sy-subrc ne 0.
        select single * from tcjet into wa_tcjet
          where proid = <fs_tcjed>-proid.
      endif.
*---------------------------------------------------------------------*
*       FORM check                                                    *
*---------------------------------------------------------------------*
* --> OBJ edmask_base to do the work                                  *
*---------------------------------------------------------------------*
form check using obj type ref to edmask_base.
  data:
    wa_dummy type tcjed,
    wa_tcjed type tcjed.
  if not p_mask is initial.
    call method obj->limit exporting mask = p_mask.
  endif.
  obj->testmode = ptest.
  obj->dialogmode = dialog.
  obj->squeezemode = autofit.