Monday, 4 December 2017

Reopen Closed Bank Accounts


Currently a bank account with the status Closed can no longer be reopened. However, in some exceptional cases, customers need to reopen bank accounts and set the status back to Active.

Solution


The bank account reopening scenario is not a standard scenario. And this only occurs in some exceptional case, therefore a workaround for this issue is provided.


  • In the system where the bank account needs to be reopened, create a local report in transaction SE38
  • Copy the following codes into your new report
  • Replace the report name 'ZFCLM_BAM_REOPENACCOUNTS' with your own report name
  • For SAP Simple Finance, on-premise edition 1503 (SP0), please comment out codes which is marked as '[TO BE COMMENTED in 1503 (SP0)]'
  • Save and activate your report
  • Run the report by specifying the bank account ID that you want to reopen

This report only processes bank accounts with the status Closed. And it requires that the executor has the authorization to modify bank accounts. Please ensure that executor has activity 02 assigned for authorization object F_CLM_BAM.


Source code for report:

*&---------------------------------------------------------------------*
*& Report ZFCLM_BAM_REOPENACCOUNTS
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zfclm_bam_reopenaccounts.
TABLES: sscrfields.
* Output structure for ALV tree
TYPES: BEGIN OF ys_alv_outtab,
acc_id TYPE fclm_bam_acc_id,
acc_num TYPE fclm_bam_acc_num,
banks TYPE banks,
bankl TYPE bankl,
currencies TYPE fclm_bam_acc_curr,
status TYPE fclm_bam_acc_status,
status_ui TYPE fclm_bam_status_ui,
description TYPE fclm_bam_description,
END OF ys_alv_outtab.
* Bank account data
DATA: ls_bam_amd TYPE fclm_bam_amd.
DATA: gt_amd TYPE fclm_bam_t_db_amd,
gt_amd_sig TYPE fclm_bam_t_db_sig,
gt_amd_lim TYPE fclm_bam_t_db_amd_lim,
gt_amd_cur TYPE fclm_bam_t_db_amd_cur,
gt_amd_t TYPE fclm_bam_t_db_amd_t,
gt_amd_aclink2 TYPE fclm_bam_t_aclink2.
* ALV variables
DATA: gt_alv_outtab TYPE TABLE OF ys_alv_outtab,
gr_cont_docking TYPE REF TO cl_gui_docking_container,
gr_container TYPE REF TO cl_gui_custom_container,
gr_alv TYPE REF TO cl_gui_alv_grid,
gt_fieldcat TYPE lvc_t_fcat,
gs_layout TYPE lvc_s_layo,
gt_exclude_button TYPE ui_functions,
gv_ok_code TYPE sy-ucomm.
"Selection screen
SELECTION-SCREEN BEGIN OF BLOCK 1.
SELECT-OPTIONS: so_accid FOR ls_bam_amd-acc_id MATCHCODE OBJECT
FCLM_BAM_SHLP_ACNTID.
SELECTION-SCREEN END OF BLOCK 1.
SELECTION-SCREEN BEGIN OF SCREEN 1010.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN FUNCTION KEY 1.
SELECTION-SCREEN END OF SCREEN 1010.
INITIALIZATION.
"Add custom button 'Reopen Accounts'
MOVE 'Reopen Accounts' TO sscrfields-functxt_01.
AT SELECTION-SCREEN OUTPUT.
DATA lt_exclude TYPE TABLE OF rsexfcode.
CASE sy-dynnr.
WHEN 1010.
"Exclude default execute button
APPEND INITIAL LINE TO lt_exclude ASSIGNING FIELD-SYMBOL(<ls_exclude>).
<ls_exclude>-fcode = 'ONLI'.
CALL FUNCTION 'RS_SET_SELSCREEN_STATUS'
EXPORTING
p_status = '%_00'
p_program = 'RSSYSTDB'
TABLES
p_exclude = lt_exclude.
"Create container for ALV display
IF gr_cont_docking IS INITIAL.
CREATE OBJECT gr_cont_docking
EXPORTING
repid = sy-repid
dynnr = '1010'
side = gr_cont_docking->dock_at_left
extension = 1700.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CREATE OBJECT gr_alv
EXPORTING
i_parent = gr_cont_docking
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDIF.
**** prepare ALV control setting
* CREATE OBJECT lr_event_receiver.
* SET HANDLER lr_event_receiver->handle_user_command FOR gr_alv.
* SET HANDLER lr_event_receiver->handle_toolbar FOR gr_alv.
*** build ALV table
PERFORM build_alv_data.
SORT gt_alv_outtab BY acc_id.
*** set layout
gs_layout-sel_mode = 'A'.
CALL METHOD gr_alv->set_table_for_first_display
EXPORTING
it_toolbar_excluding = gt_exclude_button
is_layout = gs_layout
CHANGING
* it_sort = gt_sort
it_outtab = gt_alv_outtab[]
it_fieldcatalog = gt_fieldcat[]
EXCEPTIONS
OTHERS = 1.
PERFORM init_selected_row .
WHEN OTHERS.
ENDCASE.
AT SELECTION-SCREEN ON EXIT-COMMAND.
PERFORM exit_program.
AT SELECTION-SCREEN.
CASE sy-dynnr.
WHEN 1010.
IF sscrfields-ucomm = 'FC01'.
PERFORM reopen_bankaccounts.
ENDIF.
WHEN 1000.
IF sy-ucomm EQ 'ONLI'.
PERFORM set_exclude_button.
PERFORM set_field_catalog.
PERFORM prepare_reopenaccounts.
CALL SELECTION-SCREEN 1010.
ENDIF.
WHEN OTHERS.
ENDCASE.

*&---------------------------------------------------------------------*
*& Form EXIT_PROGRAM
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM exit_program .
IF gr_container IS BOUND.
CALL METHOD gr_container->free.
ENDIF.
CALL METHOD cl_gui_cfw=>flush.
"Unlock objects
LOOP AT gt_alv_outtab ASSIGNING FIELD-SYMBOL(<ls_alv_outtab>).
CALL FUNCTION 'DEQUEUE_EFCLM_BAM_AMD'
EXPORTING
acc_id = <ls_alv_outtab>-acc_id.
ENDLOOP.
SET SCREEN 0.
LEAVE SCREEN.
ENDFORM.

*&---------------------------------------------------------------------*
*& Form REOPEN_BANKACCOUNTS
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM reopen_bankaccounts .
DATA lt_index_row TYPE lvc_t_row.
DATA lt_amd LIKE gt_amd.
DATA lt_amd_cur LIKE gt_amd_cur.
DATA lt_amd_sig LIKE gt_amd_sig.
DATA lt_amd_lim LIKE gt_amd_lim.
DATA lt_amd_t LIKE gt_amd_t.
DATA lt_amd_aclink2 LIKE gt_amd_aclink2.
DATA lt_message TYPE bapiret2_t.
DATA lv_error TYPE boolean.
"Process for each bank accounts
CALL METHOD gr_alv->get_selected_rows
IMPORTING
et_index_rows = lt_index_row.
"Prepare data for selected accounts
LOOP AT lt_index_row ASSIGNING FIELD-SYMBOL(<ls_index_row>).
READ TABLE gt_alv_outtab ASSIGNING FIELD-SYMBOL(<ls_alv_out>) INDEX <ls_index_row>-index.
CHECK sy-subrc EQ 0.
READ TABLE gt_amd ASSIGNING FIELD-SYMBOL(<ls_amd>) WITH KEY acc_id = <ls_alv_out>-acc_id.
CHECK sy-subrc EQ 0.
"Change account attributes for reopen scenario
<ls_amd>-status = if_fclm_bam_constants=>cc_account_status-active.
<ls_amd>-changed_by = sy-uname.
<ls_amd>-changed_at_dat = sy-datum.
<ls_amd>-changed_at_tim = sy-uzeit.
<ls_amd>-valid_to = '99991231'.
CLEAR <ls_amd>-planned_closing_date.
CLEAR <ls_amd>-closed_by.
CLEAR <ls_amd>-closed_at_dat.
CLEAR <ls_amd>-closed_at_tim.
APPEND <ls_amd> TO lt_amd.
LOOP AT gt_amd_cur ASSIGNING FIELD-SYMBOL(<ls_amd_cur>)
WHERE acc_id = <ls_amd>-acc_id.
APPEND <ls_amd_cur> TO lt_amd_cur.
ENDLOOP.
LOOP AT gt_amd_sig ASSIGNING FIELD-SYMBOL(<ls_amd_sig>)
WHERE acc_id = <ls_amd>-acc_id.
APPEND <ls_amd_sig> TO lt_amd_sig.
ENDLOOP.
LOOP AT gt_amd_lim ASSIGNING FIELD-SYMBOL(<ls_amd_lim>)
WHERE acc_id = <ls_amd>-acc_id.
APPEND <ls_amd_lim> TO lt_amd_lim.
ENDLOOP.
LOOP AT gt_amd_t ASSIGNING FIELD-SYMBOL(<ls_amd_t>)
WHERE acc_id = <ls_amd>-acc_id.
APPEND <ls_amd_t> TO lt_amd_t.
ENDLOOP.
LOOP AT gt_amd_aclink2 ASSIGNING FIELD-SYMBOL(<ls_amd_aclink2>)
WHERE acc_id = <ls_amd>-acc_id.
APPEND <ls_amd_aclink2> TO lt_amd_aclink2.
ENDLOOP.
ENDLOOP.
CALL FUNCTION 'FCLM_BAM_AMD_MODIFY_MULTI_CD'
EXPORTING
it_db_amd = lt_amd
it_db_amd_t = lt_amd_t
it_db_amd_cur = lt_amd_cur
it_db_amd_lim = lt_amd_lim
it_db_amd_sig = lt_amd_sig
* IV_WRITE_WITH_INITIAL =
* IV_WRITE_CD = 'X'
iv_commit = 'X'
* IV_NEEDBUFFER =
* IV_CHGDOC_TYPE = 'R'
it_aclink2 = lt_amd_aclink2 "[TO BE COMMENTED in 1503 (SP0)]
IMPORTING
* ET_ACCOUNT_CD =
et_message = lt_message
EXCEPTIONS
error_data = 1
read_account_error = 2
change_document_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
* Implement suitable error handling here
ROLLBACK WORK.
ELSE.
LOOP AT lt_message TRANSPORTING NO FIELDS WHERE type CA 'AEX'.
lv_error = abap_true.
ENDLOOP.
IF lv_error EQ abap_true.
ROLLBACK WORK.
ELSE.
COMMIT WORK.
"Unlock bank accounts
LOOP AT lt_amd ASSIGNING <ls_amd>.
CALL FUNCTION 'DEQUEUE_EFCLM_BAM_AMD'
EXPORTING
acc_id = <ls_amd>-acc_id.
DELETE gt_amd WHERE acc_id = <ls_amd>-acc_id.
ENDLOOP.
ENDIF.
ENDIF.
"Report messages by popup window
IF lv_error EQ abap_false.
MESSAGE 'Bank accounts are reopened successfully' TYPE 'I'.
ELSE.
MESSAGE 'Error when reopening bank accounts; try again' TYPE 'E'.
ENDIF.
ENDFORM.

*&---------------------------------------------------------------------*
*& Form BUILD_ALV_DATA
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM build_alv_data .
CLEAR gt_alv_outtab.
LOOP AT gt_amd ASSIGNING FIELD-SYMBOL(<ls_amd>).
APPEND INITIAL LINE TO gt_alv_outtab ASSIGNING FIELD-SYMBOL(<ls_alv_out>).
MOVE-CORRESPONDING <ls_amd> TO <ls_alv_out>.
"Get status text
<ls_alv_out>-status_ui = cl_fclm_bam_utility=>get_status_text( <ls_alv_out>-status ).
"Get description
READ TABLE gt_amd_t ASSIGNING FIELD-SYMBOL(<ls_amd_t>) WITH KEY acc_id = <ls_alv_out>-acc_id
langu = sy-langu.
IF sy-subrc EQ 0.
<ls_alv_out>-description = <ls_amd_t>-description.
ENDIF.
"Get currency
READ TABLE gt_amd_cur ASSIGNING FIELD-SYMBOL(<ls_amd_cur>) WITH KEY acc_id = <ls_alv_out>
-acc_id.
IF sy-subrc EQ 0.
<ls_alv_out>-currencies = <ls_amd_cur>-waers.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form INIT_SELECTED_ROW
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM init_selected_row .
DATA: ls_index_row TYPE LINE OF lvc_t_row,
lt_index_row TYPE lvc_t_row.
CALL METHOD gr_alv->get_selected_rows
IMPORTING
et_index_rows = lt_index_row.
IF lt_index_row IS INITIAL.
LOOP AT gt_alv_outtab ASSIGNING FIELD-SYMBOL(<ls_alv_out>).
ls_index_row-index = sy-tabix.
APPEND ls_index_row TO lt_index_row.
ENDLOOP.
CALL METHOD gr_alv->set_selected_rows
EXPORTING
it_index_rows = lt_index_row.
ENDIF.
ENDFORM.

*&---------------------------------------------------------------------*
*& Form SET_EXCLUDE_BUTTON
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM set_exclude_button .
CHECK gt_exclude_button IS INITIAL.
"APPEND cl_gui_alv_grid=>mc_fc_graph TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_expcrtempl TO gt_exclude_button.
"APPEND cl_gui_alv_grid=>mc_fc_print_prev TO gt_exclude_button.
"APPEND cl_gui_alv_grid=>mc_fc_print_back TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_sum TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_info TO gt_exclude_button.
"APPEND cl_gui_alv_grid=>mc_fc_views TO gt_exclude_button.
"APPEND cl_gui_alv_grid=>mc_mb_export TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_mb_subtot TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_mb_sum TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_loc_copy_row TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_loc_delete_row TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_loc_append_row TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_loc_insert_row TO gt_exclude_button.
"APPEND cl_gui_alv_grid=>mc_fc_sort_asc TO gt_exclude_button.
"APPEND cl_gui_alv_grid=>mc_fc_sort_dsc TO gt_exclude_button.
"APPEND cl_gui_alv_grid=>mc_fc_detail TO gt_exclude_button.
"APPEND cl_gui_alv_grid=>mc_fc_find TO gt_exclude_button.
"APPEND cl_gui_alv_grid=>mc_fc_filter TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_graph TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_loc_move_row TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_loc_copy TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_loc_cut TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_loc_paste TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_loc_paste_new_row TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_loc_undo TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_check TO gt_exclude_button.
APPEND cl_gui_alv_grid=>mc_fc_refresh TO gt_exclude_button.
ENDFORM.

*&---------------------------------------------------------------------*
*& Form SET_FIELD_CATALOG
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM set_field_catalog .
DATA lt_fieldcat LIKE gt_fieldcat.
DATA: ls_fcat TYPE lvc_s_fcat.
FIELD-SYMBOLS: <fs_fcat> TYPE lvc_s_fcat.
CHECK gt_fieldcat IS INITIAL.
CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
EXPORTING
i_structure_name = 'FCLM_BAM_S_AMD_ATT'
CHANGING
ct_fieldcat = lt_fieldcat.
LOOP AT lt_fieldcat ASSIGNING FIELD-SYMBOL(<ls_fieldcat>).
CASE <ls_fieldcat>-fieldname.
WHEN 'ACC_ID'.
<ls_fieldcat>-col_pos = 1.
WHEN 'ACC_NUM'.
<ls_fieldcat>-col_pos = 2.
<ls_fieldcat>-outputlen = 20.
WHEN 'BANKS'.
<ls_fieldcat>-col_pos = 3.
<ls_fieldcat>-outputlen = 8.
WHEN 'BANKL'.
<ls_fieldcat>-col_pos = 4.
WHEN 'CURRENCIES'.
<ls_fieldcat>-col_pos = 5.
<ls_fieldcat>-outputlen = 10.
<ls_fieldcat>-reptext = 'Currency'.
CLEAR <ls_fieldcat>-no_out.
WHEN 'DESCRIPTION'.
<ls_fieldcat>-col_pos = 6.
<ls_fieldcat>-outputlen = 30.
CLEAR <ls_fieldcat>-no_out.
WHEN 'STATUS'.
<ls_fieldcat>-tech = abap_true.
WHEN 'STATUS_UI'.
<ls_fieldcat>-col_pos = 7.
<ls_fieldcat>-outputlen = 8.
WHEN OTHERS.
CONTINUE.
ENDCASE.
APPEND <ls_fieldcat> TO gt_fieldcat.
ENDLOOP.
ENDFORM.

*&---------------------------------------------------------------------*
*& Form PREPARE_REOPENACCOUNTS
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM prepare_reopenaccounts .
DATA lt_accid TYPE fclm_bam_t_acc_id.
DATA lt_amd TYPE fclm_bam_t_db_amd.
DATA lt_unauthor_records TYPE fclm_bam_t_unauth_records.
DATA lv_lockfailure TYPE boolean.
CLEAR lt_amd.
CLEAR gt_amd.
CLEAR gt_amd_t.
CLEAR gt_amd_cur.
CLEAR gt_amd_sig.
CLEAR gt_amd_lim.
CLEAR gt_amd_aclink2.
IF so_accid IS INITIAL.
MESSAGE 'Select account ranges; or all accounts with status Closed will be selected' TYPE 'W'.
ENDIF.
SELECT acc_id INTO TABLE @lt_accid FROM fclm_bam_amd
WHERE acc_id IN @so_accid.
CALL FUNCTION 'FCLM_BAM_AMD_READ'
EXPORTING
it_acc_id = lt_accid
iv_read_activity = '02'
IMPORTING
et_db_amd = lt_amd
et_db_amd_t = gt_amd_t
et_db_amd_cur = gt_amd_cur
et_db_amd_sig = gt_amd_sig
et_db_amd_lim = gt_amd_lim
* et_db_aclink = gt_amd_aclink
et_db_aclink2 = gt_amd_aclink2
et_unauthor_records = lt_unauthor_records
EXCEPTIONS
no_record_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE 'No bank accounts found' TYPE 'E'.
ENDIF.
IF lt_unauthor_records IS NOT INITIAL.
MESSAGE 'Some unauthorized bank accounts are skipped' TYPE 'W'.
ENDIF.
"Filter those bank account with status 'Closed'
LOOP AT lt_amd ASSIGNING FIELD-SYMBOL(<ls_amd>).
CHECK <ls_amd>-status EQ if_fclm_bam_constants=>cc_account_status-closed.
"Try to lock objects
CALL FUNCTION 'ENQUEUE_EFCLM_BAM_AMD'
EXPORTING
acc_id = <ls_amd>-acc_id
langu = sy-langu
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc EQ 0.
APPEND <ls_amd> TO gt_amd.
ELSE.
IF lv_lockfailure EQ abap_false.
lv_lockfailure = abap_true.
ENDIF.
ENDIF.
ENDLOOP.
IF lv_lockfailure EQ abap_true.
MESSAGE 'Some bank accounts cannot be locked for reopen' TYPE 'W'.
ENDIF.
IF gt_amd IS INITIAL.
MESSAGE 'No accounts with status Closed exist' TYPE 'E'.
ENDIF.
ENDFORM.


No comments:

Post a Comment