
BTP - Business Configuration (Anpassung)
Wie sieht es eigentlich mit Anpassungen des RAP Business Objekts im Kontext der Business Configuration aus? Mehr Informationen in diesem Artikel.
Inhaltsverzeichnis
Wie sieht es eigentlich mit der Anpassungsfähigkeit eines Business Configuration Objekts aus? Heute schauen wir einmal auf die Möglichkeiten und was wir als Entwickler noch beeinflussen können, um das Objekt unserem Standard anzupassen und dem Anwender mehr Funktionen zur Verfügung zu stellen.
Einleitung
Die Business Configuration ist ein RAP Business Objekt, welches über den ADT Wizard im System erzeugt wird und einem gewissen Aufbau entsprechend der Einstellungen folgt. Nach der Generation steht das Objekt frei zur Bearbeitung zur Verfügung, ein Nachgenerieren von Eigenschaften oder Feldern ist dann nicht mehr so einfach möglich. Entsprechend haben wir als Entwickler nun die Möglichkeit weitere Anpassungen vorzunehmen.
Aufbau
Im ersten Schritt sollten wir verstehen, was wir beim letzten Mal eigentlich im System generiert haben. Dazu die folgende Grafik zum Aufbau des Business Objekts.
Im vorderen Teil wird das RAP BO dargestellt, dieses hat als ROOT Entität einen Singleton, eine Entität die nur einen Eintrag hat, der statisch verknüpft ist. Als Kind Entität wird unsere eigentliche Pflegetabelle angelegt, die über die SingletonID mit dem Singleton verknüpft ist. Dieses Attribut wird zur Navigation benötigt. Im Singleton wird zum Beispiel die Information zum Transportauftrag gehalten, über welchen später die Änderungen aufgezeichnet werden. Jede Entität besitzt eine Draft-Tabelle, wo die temporären Änderungen gesichert werden. Unsere eigentliche Tabelle mit den Daten befindet sich dann am Ende der Kette.
Das Konstrukt wird verwendet, um zum einen übergreifende Informationen zu speichern, wie den Transportauftrag, aber auch um im Edit-Modus direkt die Tabelle über Fiori Elements bearbeiten zu können.
Anpassungen
In den folgenden Abschnitten wollen wir das Business Objekt um verschiedene Anpassungen erweitern. Grundsätzlich stehen dir alle Erweiterungs- und Anpassungsmechanismen vom ABAP RESTful Programming Model zur Verfügung.
Texte
Im ersten Schritt wollen wir die Überschriften der Spalten anpassen, damit der Anwender weiß, was sich hinter den einzelnen Einstellungen verbirgt. Im Moment werden die erzeugten Texte verwendet. Grundsätzlich können wir für jede Spalte auch Datenelemente anlegen, so können wir die Texte dort pflegen.
In unserem Fall erweitern wir die Metadata Extension und fügen an den entsprechenden Feldern Annotationen hinzu. Hier einmal ein Beispiel für zwei Felder:
@EndUserText.label: 'Is Used'
IsUsed;
@EndUserText.label: 'Is Mandatory'
IsMandatory;
Nachdem wir nun die meisten Felder mit neuen Labels erweitert haben, erhalten wir in der Pflegeoberfläche ein neues Bild und besser beschriebene Spalten, die unserem Anwender bei der Pflege helfen.
Validierung
Im nächsten Schritt müssen wir sicherstellen, dass die Felder die korrekten Werte erhalten. Dazu können wir zum Beispiel eine Validierung implementieren, die sicherstellt, dass die Anzahl der Prozesse größer als Null ist. Dazu definieren wir in der Verhaltensdefinition eine neue Validierung.
validation ValidateProccesesAreSet on save { field Processes; create; update; }
Diese Validierung müssen wir noch in die Prepare Phase übernehmen, um die Meldung entsprechend beim Sichern zu triggern.
draft determine action Prepare {
validation BusinessConfigurati ~ ValidateProccesesAreSet;
}
Per STRG + 1 lassen wir uns die Implementierung der Methode anlegen und implementieren im Anschluss die Prüflogik. Wir lesen dazu die entsprechenden Daten über das RAP BO und prüfen im Anschluss die Datensätze. Sind die Prozesse nicht gepflegt, dann erzeugen wir einen Fehler und befüllen die FAILED und REPORTED Struktur.
METHOD ValidateProccesesAreSet.
READ ENTITIES OF zbs_i_swcbc_s IN LOCAL MODE
ENTITY BusinessConfigurati
FIELDS ( Processes ) WITH CORRESPONDING #( it_keys )
RESULT DATA(lt_entries).
LOOP AT lt_entries INTO DATA(ls_entry).
IF ls_entry-Processes = 0.
INSERT VALUE #( configid = ls_entry-ConfigId ) INTO TABLE failed-businessconfigurati.
INSERT VALUE #( configid = ls_entry-ConfigId
%msg = new_message_with_text( text = 'Field need at least one process' )
%element-Processes = if_abap_behv=>mk-on ) INTO TABLE reported-businessconfigurati.
ENDIF.
ENDLOOP.
ENDMETHOD.
Wollen wir nun einen neuen Datensatz anlegen, bei dem die Prozesse mit Null gepflegt sind. Erhalten wir die entsprechende Fehlermeldung und können die Daten nicht speichern.
Wertehilfe
Als letzte Anpassung wollen wir eine Wertehilfe für die Klasse zur Verfügung stellen, damit der Anwender aus den vorhandenen Klassen wählen kann. Dazu benötigen wir im ersten Schritt eine Suchhilfe, diese implementieren wir als Custom Entity.
@EndUserText.label: 'Working Classes VH'
@ObjectModel.query.implementedBy: 'ABAP:ZCL_BS_SWC_WORKING_QRY'
define custom entity ZBS_I_SWCWorkingClassesVH
{
key WorkingClass : abap.char(32);
Description : abap.char(60);
}
In der Query Klasse implementieren wir eine einfache Logik, die manuell unsere Ergebnistabelle aufbaut und als Wertehilfe zur Verfügung stellt. Die Implementierung ist recht einfach gehalten, wodurch das Sortieren, Filtern und andere Features nicht funktionieren. Für den vollen Funktionsumfang, müsstest du noch einiges mehr an Logik anlegen.
CLASS zcl_bs_swc_working_qry DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_rap_query_provider.
ENDCLASS.
CLASS zcl_bs_swc_working_qry IMPLEMENTATION.
METHOD if_rap_query_provider~select.
DATA lt_result TYPE STANDARD TABLE OF ZBS_I_SWCWorkingClassesVH.
DATA(ld_skip) = io_request->get_paging( )->get_offset( ).
DATA(ld_top) = io_request->get_paging( )->get_page_size( ).
DATA(lt_sorted) = io_request->get_sort_elements( ).
lt_result = VALUE #( ( WorkingClass = 'ZCL_BS_DEMO_PROCESS' Description = 'Automation process' )
( WorkingClass = 'ZCL_BS_DEMO_NO_ONE' Description = 'One automation' )
( WorkingClass = 'ZCL_TEST' Description = 'Test class' ) ).
IF io_request->is_total_numb_of_rec_requested( ).
io_response->set_total_number_of_records( 3 ).
ENDIF.
IF io_request->is_data_requested( ).
io_response->set_data( lt_result ).
ENDIF.
ENDMETHOD.
ENDCLASS.
Zum Abschluss binden wir den View als Wertehilfe in unsere Entität entsprechend am Feld ein.
@Consumption.valueHelpDefinition: [{ entity: { name: 'ZBS_I_SWCWorkingClassesVH', element: 'WorkingClass' } }]
working_class as WorkingClass,
In der Pflege wird nun hinter dem Feld der Button für die Wertehilfe angezeigt.
Wenn wir die Wertehilfe aufrufen, können wir nun aus den vorhandenen Klassen wählen, diese werden dann als Wert in die Tabelle übernommen.
Hinweis: Wenn du später die Wertehilfe in Test und Produktion nutzen willst, musst du den CDS View auch in der Service Definition freigeben (expose).
Informationen (Kopf)
Als letzten Punkt wollen wir auf der Objektseite den Header anpassen und die Beschreibung unter der Identifikation übernehmen. Im Moment sieht der Header wie folgt aus.
In der Metadata Extension können wir nun den Header erweitern.
@UI: {
headerInfo: {
typeName: 'BusinessConfigurati',
typeNamePlural: 'BusinessConfiguratis',
title: {
type: #STANDARD,
label: 'Business Configuration',
value: 'ConfigId'
},
description: {
value: 'Description'
}
}
}
Nachdem wir die DESCRIPTION hinzugefügt haben und mit dem entsprechenden Feld der CDS Entität verbunden haben, erhalten wir nach dem Neuladen der Objektseite ein neues Bild.
Vollständiges Beispiel
Alle Änderungen an den verschiedenen Objekten findest du über das GitHub Repository der Software Komponente (SWC) im entsprechenden Commit. Die Struktur des GitHub Repository unterscheidet sich stark von der Struktur eines Repository, welches über abapGit angelegt wurde und ist nicht ganz so gut lesbar.
Fazit
Die Anpassung des Objekts können wir einfach durchführen und sollen hier sogar selbst Hand anlegen, um die Pflege nutzerfreundlicher zu machen. Entsprechend den Möglichkeiten von RAP stehen uns alle Möglichkeiten zur Verfügung, um die Daten zu validieren oder zusätzliche Suchhilfen anzubieten.