How to use I_JournalEntryTP in custom RAP BO
2023-10-27 03:37:59 Author: blogs.sap.com(查看原文) 阅读量:17 收藏

Business Object Journal Entry (I_JournalEntryTP) is available in S/4 HANA Cloud environment. It provides operations:

  • Post
  • Validate
  • Reverse
  • Change

You can try to build your own ‘Posting’ Fiori application by creating custom RAB business object. The posting can be achieved by calling the ‘Post’ action in Journal Entry object.

This blog will show a sample demo. Please note: This demo is only a demonstration of the technology and does not provide any guidance for the business.

The Fiori application will look like:

Worklist

Worklist

Input%20Transactional%20Data

Input Transactional Data

Save

Save

Steps:

  1. Create transaction & draft tables
    1. Create header table.
      @EndUserText.label : 'Journal Entry Header'
      @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
      @AbapCatalog.tableCategory : #TRANSPARENT
      @AbapCatalog.deliveryClass : #A
      @AbapCatalog.dataMaintenance : #RESTRICTED
      define table zgje_header {
      
        key client            : abap.clnt not null;
        key uuid              : sysuuid_x16 not null;
        bukrs                 : bukrs;
        gjahr                 : gjahr;
        belnr                 : belnr_d;
        waers                 : waers;
        bldat                 : bldat;
        budat                 : budat;
        bktxt                 : bktxt;
        created_by            : abp_creation_user;
        created_at            : abp_creation_tstmpl;
        last_changed_by       : abp_lastchange_user;
        last_changed_at       : abp_lastchange_tstmpl;
        local_last_changed_at : abp_locinst_lastchange_tstmpl;
      
      }​
    2. Create item table
      @EndUserText.label : 'Journal Entry Item'
      @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
      @AbapCatalog.tableCategory : #TRANSPARENT
      @AbapCatalog.deliveryClass : #A
      @AbapCatalog.dataMaintenance : #RESTRICTED
      define table zgje_item {
      
        key client                 : abap.clnt not null;
        key uuid                   : sysuuid_x16 not null;
        key buzei                  : buzei not null;
        @Semantics.amount.currencyCode : 'zgje_header.waers'
        wrbtr                      : fins_vwcur12;
        sgtxt                      : sgtxt;
        hkont                      : hkont;
        kostl                      : kostl;
        prctr                      : prctr;
        item_created_by            : abp_creation_user;
        item_created_at            : abp_creation_tstmpl;
        item_last_changed_by       : abp_lastchange_user;
        item_last_changed_at       : abp_lastchange_tstmpl;
        item_local_last_changed_at : abp_locinst_lastchange_tstmpl;
      
      }​
    3. Create draft table for header
      @EndUserText.label : 'Journal Entry Header Draft Table'
      @AbapCatalog.enhancement.category : #EXTENSIBLE_ANY
      @AbapCatalog.tableCategory : #TRANSPARENT
      @AbapCatalog.deliveryClass : #A
      @AbapCatalog.dataMaintenance : #RESTRICTED
      define table zgje_header_d {
      
        key mandt             : mandt not null;
        key uuid              : sysuuid_x16 not null;
        belnr                 : belnr_d;
        bukrs                 : bukrs;
        gjahr                 : gjahr;
        waers                 : waers;
        bldat                 : bldat;
        budat                 : budat;
        bktxt                 : bktxt;
        created_by            : abp_creation_user;
        created_at            : abp_creation_tstmpl;
        last_changed_by       : abp_lastchange_user;
        last_changed_at       : abp_lastchange_tstmpl;
        local_last_changed_at : abp_locinst_lastchange_tstmpl;
        "%admin"              : include sych_bdl_draft_admin_inc;
      
      }​
    4. Create draft table for item
      @EndUserText.label : 'Journal Entry Item Draft'
      @AbapCatalog.enhancement.category : #EXTENSIBLE_ANY
      @AbapCatalog.tableCategory : #TRANSPARENT
      @AbapCatalog.deliveryClass : #A
      @AbapCatalog.dataMaintenance : #RESTRICTED
      define table zgje_item_d {
      
        key mandt            : mandt not null;
        key uuid             : sysuuid_x16 not null;
        key buzei            : buzei not null;
        @Semantics.amount.currencyCode : 'zgje_item_d.waers'
        wrbtr                : fins_vwcur12;
        waers                : waers;
        sgtxt                : sgtxt;
        hkont                : hkont;
        kostl                : kostl;
        prctr                : prctr;
        item_created_by      : abp_creation_user;
        item_created_at      : abp_creation_tstmpl;
        item_last_changed_by : abp_lastchange_user;
        item_last_changed_at : abp_lastchange_tstmpl;
        "%admin"             : include sych_bdl_draft_admin_inc;
      
      }​
  2. Define business object structure
    1. Header root view.
      @AccessControl.authorizationCheck: #NOT_REQUIRED
      @EndUserText.label: 'GL Journal Entry'
      define root view entity ZR_GeneralJournalEntry
        as select from zgje_header
        composition [0..*] of ZR_GeneralJournalEntryItem as _Item
      {
        key uuid                  as Uuid,
            belnr                 as belnr,
            bukrs                 as Bukrs,
            gjahr                 as Gjahr,
            waers                 as Waers,
            bldat                 as Bldat,
            budat                 as Budat,
            bktxt                 as Bktxt,
            @Semantics.user.createdBy: true
            created_by            as Created_By,
            @Semantics.systemDateTime.createdAt: true
            created_at            as Created_At,
            @Semantics.user.lastChangedBy: true
            last_changed_by       as Last_Changed_By,
            @Semantics.systemDateTime.lastChangedAt: true
            last_changed_at       as Last_Changed_At,
            @Semantics.systemDateTime.localInstanceLastChangedAt: true
            local_last_changed_at as Local_Last_Changed_At,
            _Item
      
      }
      ​
    2. Item child view
      @AbapCatalog.viewEnhancementCategory: [#NONE]
      @AccessControl.authorizationCheck: #NOT_REQUIRED
      @EndUserText.label: 'GL Journal Entry Item'
      @Metadata.ignorePropagatedAnnotations: true
      @ObjectModel.usageType:{
        serviceQuality: #X,
        sizeCategory: #S,
        dataClass: #MIXED
      }
      define view entity ZR_GeneralJournalEntryItem
        as select from zgje_item
        association to parent ZR_GeneralJournalEntry as _Header on $projection.Uuid = _Header.Uuid
      {
        key uuid                 as Uuid,
        key buzei                as Buzei,
            @Semantics.amount.currencyCode: 'Waers'
            wrbtr                as Wrbtr,
            _Header.Waers        as Waers,
            sgtxt                as sgtxt,
            hkont                as hkont,
            kostl                as Kostl,
            prctr                as Prctr,
            @Semantics.user.createdBy: true
            item_created_by      as Item_Created_By,
            @Semantics.systemDateTime.createdAt: true
            item_created_at      as Item_Created_At,
            @Semantics.user.lastChangedBy: true
            item_last_changed_by as Item_Last_Changed_By,
            @Semantics.systemDateTime.localInstanceLastChangedAt: true
            item_last_changed_at as Item_Last_Changed_At,
            _Header
      }
      ​
  3. Create class for local transactional buffer.which will be used in behavior pool implementation.
    CLASS zgje_transaction_handler DEFINITION
      PUBLIC
      FINAL
      CREATE PUBLIC .
    
      PUBLIC SECTION.
    
        CLASS-DATA: go_instance TYPE REF TO zgje_transaction_handler.
    
        CLASS-METHODS: get_instance RETURNING VALUE(result) TYPE REF TO zgje_transaction_handler.
    
        TYPES: BEGIN OF ty_temp_key,
                 cid TYPE abp_behv_cid,
                 pid TYPE abp_behv_pid,
               END OF ty_temp_key,
               tt_temp_key TYPE STANDARD TABLE OF ty_temp_key WITH DEFAULT KEY,
               BEGIN OF ty_final_key,
                 cid   TYPE abp_behv_cid,
                 bukrs TYPE bukrs,
                 belnr TYPE belnr_d,
                 gjahr TYPE gjahr,
               END OF ty_final_key,
               tt_final_key type STANDARD TABLE OF ty_final_key WITH DEFAULT KEY,
               tt_header  TYPE STANDARD TABLE OF zgje_header WITH DEFAULT KEY.
    
    
        DATA: temp_key     TYPE tt_temp_key.
    
    
        METHODS: set_temp_key IMPORTING it_temp_key TYPE tt_temp_key,
          convert_temp_to_final RETURNING VALUE(result) TYPE tt_final_key,
          additional_save IMPORTING it_create type tt_header
                                     it_delete TYPE tt_header,
          clean_up.
    
      PROTECTED SECTION.
      PRIVATE SECTION.
    ENDCLASS.
    
    
    
    CLASS zgje_transaction_handler IMPLEMENTATION.
      METHOD get_instance.
        IF go_instance IS NOT BOUND.
          go_instance = NEW #( ).
        ENDIF.
        result = go_instance.
      ENDMETHOD.
    
      METHOD additional_save.
    
        data: lt_create type TABLE of zgje_header.
    
        DATA(lt_je_key) = convert_temp_to_final(  ).
    
        loop at it_create into data(ls_create).
          read TABLE lt_je_key into data(ls_je_key) with key cid = ls_create-uuid.
          if sy-subrc = 0.
          ls_create-belnr = ls_je_key-belnr.
          append ls_create to lt_create.
          endif.
        ENDLOOP.
    
        IF lt_create IS NOT INITIAL.
          INSERT zgje_header FROM TABLE @lt_create.
        ENDIF.
    
        IF it_delete IS NOT INITIAL.
          DELETE zgje_header FROM TABLE @it_delete.
        ENDIF.
    
      ENDMETHOD.
    
      METHOD clean_up.
        CLEAR temp_key.
      ENDMETHOD.
    
      METHOD convert_temp_to_final.
        DATA: ls_final_key TYPE ty_final_key.
        IF temp_key IS NOT INITIAL.
          LOOP AT temp_key INTO DATA(ls_temp_key).
            CONVERT KEY OF i_journalentrytp
              FROM ls_temp_key-pid
              TO FINAL(lv_root_key).
    
            ls_final_key-cid = ls_temp_key-cid.
            ls_final_key-bukrs = lv_root_key-companycode.
            ls_final_key-belnr = lv_root_key-accountingdocument.
            ls_final_key-gjahr = lv_root_key-fiscalyear.
    
            APPEND ls_final_key TO result.
          ENDLOOP.
        ENDIF.
      ENDMETHOD.
    
      METHOD set_temp_key.
        temp_key = it_temp_key.
      ENDMETHOD.
    
    ENDCLASS.
    ​
  4. Define behavior
    managed with additional save
    implementation in class zbp_r_generaljournalentry unique;
    strict ( 2 );
    with draft;
    
    define behavior for ZR_GeneralJournalEntry //alias <alias_name>
    //persistent table zgje_header
    with unmanaged save
    draft table zgje_header_d
    lock master
    total etag Last_Changed_At
    authorization master ( instance )
    etag master Local_Last_Changed_At
    {
      create;
      update ;
      delete ;
      association _Item { create; with draft; }
      draft action Resume;
      draft action Edit;
      draft action Activate optimized;
      draft action Discard;
      draft determine action Prepare;
    
      determination Post on save {create;}
      mapping for zgje_header corresponding;
      field ( readonly, numbering : managed ) Uuid;
      field ( readonly ) belnr;
    }
    
    define behavior for ZR_GeneralJournalEntryItem //alias <alias_name>
    persistent table zgje_item
    draft table zgje_item_d
    lock dependent by _Header
    authorization dependent by _Header
    etag master Item_Last_Changed_At
    {
      update ;
      delete ;
      field ( readonly ) Uuid;
      field ( mandatory: create,readonly : update ) Buzei;
      association _Header { with draft; }
      mapping for zgje_item corresponding;
    }​
  5. Use ADT tool to generate behavior pool calss. Double click highlight code.Behvior%20pool
  6. Implementation of behavior pool (local type).
    CLASS lhc_zr_generaljournalentry DEFINITION INHERITING FROM cl_abap_behavior_handler.
      PRIVATE SECTION.
    
        METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
          IMPORTING keys REQUEST requested_authorizations FOR zr_generaljournalentry RESULT result.
    
        METHODS post FOR DETERMINE ON SAVE
          IMPORTING keys FOR zr_generaljournalentry~post.
    
    ENDCLASS.
    
    CLASS lhc_zr_generaljournalentry IMPLEMENTATION.
    
      METHOD get_instance_authorizations.
      ENDMETHOD.
    
      METHOD post.
    
        DATA: lt_entry    TYPE TABLE FOR ACTION IMPORT i_journalentrytp~post,
              ls_entry    LIKE LINE OF lt_entry,
              ls_glitem   LIKE LINE OF ls_entry-%param-_glitems,
              ls_amount   LIKE LINE OF ls_glitem-_currencyamount,
              lt_temp_key TYPE zgje_transaction_handler=>tt_temp_key,
              ls_temp_key LIKE LINE OF lt_temp_key.
    
        READ ENTITIES OF zr_generaljournalentry IN LOCAL MODE
            ENTITY zr_generaljournalentry ALL FIELDS WITH CORRESPONDING #( keys ) RESULT FINAL(header)
            ENTITY zr_generaljournalentry BY \_item ALL FIELDS WITH CORRESPONDING #( keys ) RESULT FINAL(item).
    
        "start to call I_JournalEntryTP~Post
        LOOP AT header REFERENCE INTO DATA(ls_header).
          CLEAR ls_entry.
          ls_entry-%cid = ls_header->uuid. "use UUID as CID
          ls_entry-%param-companycode = ls_header->bukrs.
          ls_entry-%param-businesstransactiontype = 'RFPO'.
          ls_entry-%param-accountingdocumenttype = 'AB'.
          ls_entry-%param-accountingdocumentheadertext = ls_header->bktxt.
          ls_entry-%param-documentdate = ls_header->bldat.
          ls_entry-%param-postingdate = ls_header->budat.
          ls_entry-%param-createdbyuser = ls_header->created_by.
    
          LOOP AT item REFERENCE INTO DATA(ls_item) USING KEY entity WHERE uuid = ls_header->uuid.
            CLEAR ls_glitem.
            ls_glitem-glaccountlineitem = ls_item->%data-buzei.
            ls_glitem-glaccount         = ls_item->%data-hkont.
            ls_glitem-costcenter        = ls_item->%data-kostl.
            ls_glitem-profitcenter        = ls_item->%data-prctr.
            ls_glitem-documentitemtext       = ls_item->%data-sgtxt.
    
            CLEAR ls_amount.
            ls_amount-currencyrole = '00'.
            ls_amount-currency = ls_header->waers.
            ls_amount-journalentryitemamount = ls_item->%data-wrbtr.
            APPEND ls_amount TO ls_glitem-_currencyamount.
            APPEND ls_glitem TO ls_entry-%param-_glitems.
          ENDLOOP.
          APPEND ls_entry TO lt_entry.
        ENDLOOP.
    
        IF lt_entry IS NOT INITIAL.
          MODIFY ENTITIES OF i_journalentrytp
          ENTITY journalentry
          EXECUTE post FROM lt_entry
            MAPPED FINAL(ls_post_mapped)
            FAILED FINAL(ls_post_failed)
            REPORTED FINAL(ls_post_reported).
    
          IF ls_post_failed IS NOT INITIAL.
            LOOP AT ls_post_reported-journalentry INTO DATA(ls_report).
              APPEND VALUE #( uuid = ls_report-%cid
                              %create = if_abap_behv=>mk-on
                              %is_draft = if_abap_behv=>mk-on
                              %msg = ls_report-%msg ) TO reported-zr_generaljournalentry.
            ENDLOOP.
          ENDIF.
    
          LOOP AT ls_post_mapped-journalentry INTO DATA(ls_je_mapped).
            ls_temp_key-cid = ls_je_mapped-%cid.
            ls_temp_key-pid = ls_je_mapped-%pid.
            APPEND ls_temp_key TO lt_temp_key.
          ENDLOOP.
    
        ENDIF.
    
        zgje_transaction_handler=>get_instance( )->set_temp_key( lt_temp_key ).
    
      ENDMETHOD.
    
    
    ENDCLASS.
    
    CLASS lsc_zr_generaljournalentry DEFINITION INHERITING FROM cl_abap_behavior_saver.
      PROTECTED SECTION.
    
        METHODS save_modified REDEFINITION.
    
        METHODS cleanup_finalize REDEFINITION.
    
    ENDCLASS.
    
    CLASS lsc_zr_generaljournalentry IMPLEMENTATION.
    
      METHOD save_modified.
        "unmanaged save for table ZGJE_HEADER
        DATA: Lt_create type TABLE of ZGJE_HEADER,
              lt_delete type TABLE of ZGJE_HEADER.
    
    
        lt_create = CORRESPONDING #( create-zr_generaljournalentry mapping from entity ).
        lt_delete = CORRESPONDING #( delete-zr_generaljournalentry mapping from entity ).
        zgje_transaction_handler=>get_instance( )->additional_save( it_create = lt_create
                                                                    it_delete = lt_delete ).
    
      ENDMETHOD.
    
      METHOD cleanup_finalize.
        zgje_transaction_handler=>get_instance( )->clean_up( ).
      ENDMETHOD.
    
    ENDCLASS.​
  7. Create projection business object.
    1. Header projection root view
      @EndUserText.label: 'GL Journal Entry Projection'
      @AccessControl.authorizationCheck: #NOT_REQUIRED
      @Metadata.allowExtensions: true
      define root view entity ZC_GeneralJournalEntry
        provider contract transactional_query
        as projection on ZR_GeneralJournalEntry
      {
        key Uuid,
            belnr,
            Bukrs,
            Gjahr,
            Waers,
            Bldat,
            Budat,
            Bktxt,
            @Semantics.user.createdBy: true
            Created_By,
            @Semantics.systemDateTime.createdAt: true
            Created_At,
            @Semantics.user.lastChangedBy: true
            Last_Changed_By,
            @Semantics.systemDateTime.lastChangedAt: true
            Last_Changed_At,
            @Semantics.systemDateTime.localInstanceLastChangedAt: true
            Local_Last_Changed_At,
            _Item : redirected to composition child ZC_GeneralJournalEntryItem 
      }
      ​
    2. Item projection view.
      @EndUserText.label: 'GL Journal Item Projection'
      @AccessControl.authorizationCheck: #NOT_REQUIRED
      @Metadata.allowExtensions: true
      define view entity ZC_GeneralJournalEntryItem 
      as projection on ZR_GeneralJournalEntryItem
      {
        key Uuid,                 
        key Buzei,                
            @Semantics.amount.currencyCode: 'Waers'
            Wrbtr,                
            Waers,        
            sgtxt,               
            hkont,                
            Kostl,                
            Prctr,               
            @Semantics.user.createdBy: true
            Item_Created_By,      
            @Semantics.systemDateTime.createdAt: true
            Item_Created_At,      
            @Semantics.user.lastChangedBy: true
            Item_Last_Changed_By, 
            @Semantics.systemDateTime.localInstanceLastChangedAt: true
            Item_Last_Changed_At, 
            _Header : redirected to parent ZC_GeneralJournalEntry
      }
      ​
  8. Create metadata extension
    1. Metadata extension for header projection view
      @Metadata.layer: #CUSTOMER
      annotate view ZC_GeneralJournalEntry with
      {
        @UI.facet: [ { id:              'Header',
                         purpose:         #STANDARD,
                         type:            #IDENTIFICATION_REFERENCE,
                         label:           'Entry',
                         position:        10 } ,
                       { id:              'Items',
                         purpose:         #STANDARD,
                         type:            #LINEITEM_REFERENCE,
                         label:           'Items',
                         position:        20,
                         targetElement:   '_Item'}]
      
      //  @UI.identification: [{ position: 10 }]
      //  Uuid;
        @Consumption.valueHelpDefinition: [{ entity: { name:'I_CompanyCode', element: 'CompanyCode'  } }]
        @UI: { lineItem: [{ position: 10}],selectionField: [{ position: 10 }],identification: [{ position: 20 }] }
        Bukrs;
        @UI: { lineItem: [{ position: 20}],selectionField: [{ position: 20 }],identification: [{ position: 30 }] }
        Gjahr;
        @UI: { lineItem: [{ position: 30}],selectionField: [{ position: 30 }],identification: [{ position: 40 }] }
        @Consumption.semanticObject: 'AccountingDocument'
        belnr;
        @Consumption.valueHelpDefinition: [{ entity: { name:'I_Currency', element: 'Currency'  } }]
        @UI: { lineItem: [{ position: 40}],selectionField: [{ position: 40 }],identification: [{ position: 50 }] }
        Waers;
        @UI: { lineItem: [{ position: 50}],selectionField: [{ position: 50 }],identification: [{ position: 60 }] }
        Bldat;
      
        @UI: { lineItem: [{ position: 60}],selectionField: [{ position: 60 }],identification: [{ position: 70 }] }
        Budat;
      
        @UI: { lineItem: [{ position: 70}],identification: [{ position: 80 }] }
        Bktxt;
      
      }​
    2. Metadata extension for item projection view
      @Metadata.layer: #CUSTOMER
      annotate view ZC_GeneralJournalEntryItem with
      {
        @UI.facet: [ { id:              'Item',
                       purpose:         #STANDARD,
                       type:            #IDENTIFICATION_REFERENCE,
                       label:           'Item',
                       position:        10 } ]
        @UI: { lineItem: [{ position: 10}],identification: [{ position: 10 }] }
        Buzei;
        @UI: { lineItem: [{ position: 20}],identification: [{ position: 20 }] }
        sgtxt;
        @UI: { lineItem: [{ position: 30}],identification: [{ position: 30 }] }
        Wrbtr;
        @UI: { lineItem: [{ position: 40}],identification: [{ position: 40 }] }
        @Consumption.valueHelpDefinition: [{ entity: { name:'I_GLAccount', element: 'GLAccount'  } }]
        hkont;
        @UI: { lineItem: [{ position: 50}],identification: [{ position: 50 }] }
        @Consumption.valueHelpDefinition: [{ entity: { name:'I_CostCenter', element: 'CostCenter'  } }]
        Kostl;
        @UI: { lineItem: [{ position: 60}],identification: [{ position: 60 }] }
        @Consumption.valueHelpDefinition: [{ entity: { name:'I_ProfitCenterStdVH', element: 'ProfitCenter'  } }]
        Prctr;
      
      }​
  9. Behavior projection .
    projection;
    strict ( 2 );
    use draft;
    
    define behavior for ZC_GeneralJournalEntry //alias <alias_name>
    {
      use create;
      use update;
      use delete;
    
      use action Resume;
      use action Edit;
      use action Activate;
      use action Discard;
      use action Prepare;
    
      use association _Item { create; with draft; }
    }
    
    define behavior for ZC_GeneralJournalEntryItem //alias <alias_name>
    {
      use update;
      use delete;
    
      use association _Header { with draft; }
    }​
  10. Right click view ZC_GeneralJournalEntry on the left tree navigation, choose ‘New Service Definition’.
    @EndUserText.label: 'Manage_GL_Posting'
    define service Z_EXT_GL_POSTING {
      expose ZC_GeneralJournalEntry;
      expose ZC_GeneralJournalEntryItem;
    }​
  11. Right click service definition that created in step 10, choose ‘New Service Binding’., Give a name and binding type Odata V4 – UI. Activate and publish. Use ‘Preview’ button to test. Publish_and_preview

文章来源: https://blogs.sap.com/2023/10/26/how-to-use-i_journalentrytp-in-custom-rap-bo/
如有侵权请联系:admin#unsafe.sh