
ABAP - BOPF Aktion
Du benötigst zusätzliche Prozesse auf deinem Datenmodell? Heute zeigen wir dir, wie du einfache Aktionen nach außen publizieren kannst.
Inhaltsverzeichnis
Es sollen verschieden Aktionen auf dem Datenmodell verfügbar sein, die jeder Nutzer des BOPF ausführen soll? Im heutigen Artikel zeigen wir dir anhand der "Unterzeichnung eines Partners", wie solch eine Aktion aussehen kann. Die Aktionen sind nach Außen publizierte und gesammelte Änderungen am Datenmodell, die dem Nutzer zur Verfügung gestellt werden.
Aktion anlegen
Im ersten Schritt legen wir die Aktion auf der obersten Ebene, dem Vertrag, an. Der Grund ist, dass die verschiedenen Partner in der echten Welt auch auf dem Vertrag unterschreiben und nicht auf den Partnerdaten.
Wieder muss Name und Bezeichnung eingegeben werden, um die Daten zu vervollständigen. Der Name der Klasse kann über den Vorschlag im Kontext-Menü erzeugt werden (mehr dazu bei den Ermittlungen). Als Import-Parameter soll die Partnerstruktur dienen, da der neue Partner einen Vertrag unterzeichnen soll.
Im letzten Schritt haben wir auch eine Kardinalität der Änderung eingestellt. Dabei gibt es drei Optionen die gewählt werden können: Die Arbeit auf einem, mehreren Knoten oder keinem Knoten. In unserem Fall wollen wir nur mit einem Vertrag arbeiten.
Implementierung
Die Logik implementieren wir in der neuen Klasse die das Interface /BOBF/IF_FRW_ACTION implementiert. In der Methode EXECUTE wird die Logik der Umsetzung entwickelt und alle angesprochenen Knoten bearbeitet. Für die Implementierung ein kleines Beispiel:
DATA:
lt_partners TYPE ztest_t_partners,
ls_new TYPE ztest_s_partners,
ls_param TYPE ztest_s_partners.
eo_message = /bobf/cl_frw_factory=>get_message( ).
IF lines( it_key ) <> 1.
et_failed_key = it_key.
eo_message->add_message(
EXPORTING
is_msg = VALUE #( msgty = 'E'
msgid = 'ZTEST_MSG'
msgno = '003'
)
).
RETURN.
ENDIF.
ASSIGN is_parameters->* TO FIELD-SYMBOL(<ls_param>).
IF sy-subrc = 0.
ls_param = CORRESPONDING #( <ls_param> ).
ELSE.
et_failed_key = it_key.
eo_message->add_message(
EXPORTING
is_msg = VALUE #( msgty = 'E'
msgid = 'ZTEST_MSG'
msgno = '004'
)
).
RETURN.
ENDIF.
Den ersten Teil des Codings bauen wir die Nachrichten-Instanz auf, da wir hier weitere Daten validieren und prüfen, ob Daten übergeben wurden. Wurde mehr als ein Schlüssel übergeben oder fehlen die Partnerdaten, dann lösen wir einen entsprechenden Fehler aus.
io_read->retrieve_by_association(
EXPORTING
iv_node = zif_tst_bopf_c=>sc_node-contract
it_key = it_key
iv_association = zif_tst_bopf_c=>sc_association-contract-partners
iv_fill_data = abap_true
IMPORTING
et_data = lt_partners
).
READ TABLE lt_partners
WITH KEY rltyp = ls_param-rltyp
partner = ls_param-partner
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
et_failed_key = it_key.
eo_message->add_message(
EXPORTING
is_msg = VALUE #( msgty = 'E'
msgid = 'ZTEST_MSG'
msgno = '002'
)
).
RETURN.
ENDIF.
ls_new-partner = ls_param-partner.
ls_new-rltyp = ls_param-rltyp.
io_modify->create(
EXPORTING
iv_node = zif_tst_bopf_c=>sc_node-partners
is_data = REF #( ls_new )
iv_assoc_key = zif_tst_bopf_c=>sc_association-partners-to_parent
iv_source_node_key = zif_tst_bopf_c=>sc_node-contract
iv_source_key = it_key[ 1 ]-key
iv_root_key = it_key[ 1 ]-key
IMPORTING
ev_key = DATA(ld_key)
).
Im zweiten Teil lesen wir alle Partnerdaten zum Vertrag über eine Assoziation aus und validieren noch die aktuellen Partner gegen den neuen Satz. Ist alles in Ordnung fügen wir den neuen Datensatz in die Datenbank ein und die Unterzeichnung des Vertrags ist abgeschlossen.
Programm
Für den Test der Aktion wollen wir dir eine Implementierung in einem Programm zeigen, die ohne BOBT auskommt und wie es wahrscheinlich in der echten Welt aussehen würde:
DATA(lo_tmgr) = /bobf/cl_tra_trans_mgr_factory=>get_transaction_manager( ).
DATA(lo_smgr) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( zif_tst_bopf_c=>sc_bo_key ).
DATA(ls_parameters) = VALUE ztest_s_partners(
rltyp = 'BUP001'
partner = '0000888002'
).
lo_smgr->do_action(
EXPORTING
iv_act_key = zif_tst_bopf_c=>sc_action-contract-partner_sign
it_key = VALUE #( ( key = '42D85ED56C0A1ED9B7D7FC8BAC534005' ) )
is_parameters = REF #( ls_parameters )
IMPORTING
et_failed_key = DATA(lt_failed)
eo_message = DATA(lo_msg)
).
IF lt_failed IS INITIAL.
lo_tmgr->save(
IMPORTING
ev_rejected = DATA(ld_reject)
et_rejecting_bo_key = DATA(lt_keys)
).
ENDIF.
IF ld_reject = abap_true.
lo_tmgr->cleanup( ).
ENDIF.
In unserem Beispiel sind die Daten und der zu ändernde Eintrag fest codiert, hier sollte eine dynamische Ermittlung durchgeführt werden und über den Vertrag gelesen werden. Wenn die Aktion erfolgreich durchgeführt wurde und die Tabelle lt_failed leer ist, können die Daten auf die Datenbank persistiert werden.
Test
In der Transaktion BOBT kann nach dem Laden eines Vertrags die Aktion im oberen Kontext-Menü gefunden werden, dort werden alle verfügbaren Aktionen aufgelistet.
Nach Ausführung der Aktion erscheint ein Popup mit den erwarteten Importdaten die befüllt oder zum Test auch leer gelassen werden können. Nach Bestätigung dieses Popup wird die Aktion ausgeführt und der eigene Code durchlaufen.
Ist zum Beispiel ein Partnersatz bereits enthalten, kommt es wie bei den Validierungen zu einer Fehlermeldung. Über die Buttons hinter der Nachricht kann auch in den Quellcode navigiert werden, wo die Nachricht erzeugt wurde. Da wir Knoten und Schlüssel bei der Meldungserzeugung leer gelassen haben, fehlen die Informationen in der Anzeige.
Fazit
Bereitstellung von Aktionen für das Datenmodell sollte nun für dich kein Problem mehr sein. Mit unserem Tipp kannst du die Daten im Modell abhängig von der Aktion steuern, anpassen und Zustandsänderungen verursachen.