RAP - Draft
In diesem Artikel wirst du mehr über das Draft Handling innerhalb eines Business Objekts erfahren und wie du es bei einem bestehenden Objekt implementieren kannst.
Inhaltsverzeichnis
Was passiert eigentlich, wenn ein User aufhört an der App zu arbeiten und an einem anderen Gerät die App neu aufruft? Richtig, es ist nichts mehr von seinem aktuellen Arbeitsstand verfügbar. Heute wollen wir dir zeigen, wie du diesen Umstand änderst und dem User eine Möglichkeit schaffst, an seinem zweiten Gerät weiterzuarbeiten, ohne die Eingaben zu verlieren.
Einleitung
Was ist eigentlich das Draft Handling? Hierbei handelt es sich um eine Technik, nach jedem Schritt für den User den aktuellen Stand im Backend, in einer Art Schattentabelle, zu speichern. Die Daten stehen damit erst einmal nicht in der Tabelle mit den echten Daten, es handelt sich um einen Arbeitsstand der Änderungen. Dafür musst du die Schattentabelle anlegen und das RAP Business Objekt an einigen Stellen erweitern.
Vorbereitung
Bevor wir allerdings mit der Änderung im RAP loslegen können, müssen wir eine Vorrausetzung schaffen. Es wird ein eindeutiger Zeitstempel benötigt, der den Stand der letzten Änderung beschreibt, dass sogenannte ETAG Feld. Dieses muss in jeder Datentabelle vorhanden sein, damit das System weiß, ob sich in der Zwischenzeit ein Datensatz geändert hat. Dazu erweitern wir die Partnertabelle ZBS_DMO_PARTNER um ein neues Feld:
@EndUserText.label : 'Partner Data'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zbs_dmo_partner {
key client : abap.clnt not null;
key partner : abap.char(10) not null;
name : abap.char(60);
street : abap.char(80);
city : abap.char(60);
country : land1;
payment_currency : abap.cuky;
last_changed_at : timestampl;
}
Am Ende fügen wir ein neues Feld "last_changed_at" mit dem Typen "timestampl" ein. Dieses Feld wird die Information der letzten Änderung enthalten. Nach dem Aktivieren der Tabelle müssen wir noch den Viewstack des RAP Objekts erweitern und das Feld übernehmen. Der Interface View sieht nun wie folgt aus:
define root view entity ZBS_I_RAPPartner
as select from zbs_dmo_partner
{
key partner as PartnerNumber,
name as PartnerName,
street as Street,
city as City,
country as Country,
payment_currency as PaymentCurrency,
last_changed_at as LastChangedAt
}
Wir übernehmen es erst einmal nicht in den Consumption View, da wir es nicht ausgeben wollen, sondern nur die Information für die Verarbeitung benötigen.
Verhaltensdefinition
Im nächsten Schritt können wir nun die eigentliche Erweiterung des Business Objekts angehen. Dazu ergänzen wir in der Verhaltensdefinition den Zusatz "with draft" um das Draft Handling zu aktivieren. Die weiteren Schritte sind nun in den Unterabschnitten erklärt.
with draft;
Draft Tabelle
Als Nächstes muss unter der Tabelle der Daten noch die Draft Tabelle angegeben werden. Das System wird eine entsprechende Fehlermeldung ausgeben, da die Tabelle noch nicht existiert. Über STRG + 1 kannst du dann die Tabelle automatisch anlegen lassen.
Die Tabelle wurde nun wie folgt vom System definiert:
@EndUserText.label : 'Draft table for entity ZBS_I_RAPPARTNER'
@AbapCatalog.enhancement.category : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zbs_dmo_dpartner {
key mandt : mandt not null;
key partnernumber : abap.char(10) not null;
key draftuuid : sdraft_uuid not null;
partnername : abap.char(60);
street : abap.char(80);
city : abap.char(60);
country : land1;
paymentcurrency : abap.cuky;
lastchangedat : timestampl;
"%admin" : include sych_bdl_draft_admin_inc;
}
Die Felder entsprechen vom Namen her den Feldern des Interface Views. Der Schlüssel ist um ein zusätzliches Element erweitert und am Ende der Tabelle werden einige Verwaltungsdaten definiert. Die Namen der Felder sollten nicht geändert werden und immer dem CDS Views entsprechen.
ETAG Feld
Das neue Feld muss nun noch ins Mapping, am Ende der Verhaltensdefinition, übernommen werden und der "lock master" muss um das Feld ergänzt werden, sowie ein allgemeines ETAG als "master" definiert werden.
lock master total etag LastChangedAt
authorization master ( instance )
late numbering
etag master LastChangedAt
Aktionen
Eine weitere Voraussetzung ist die Implementierung der verschiedenen Draft-Aktionen, die das Framework zur Verfügung stellt. In der Funktion "Prepare" können Validierungen hinterlegt werden, die wir definiert haben und die ausgeführt werden, bevor ein Draft in die produktive Tabelle übernommen wird.
draft action Resume;
draft action Edit;
draft action Activate;
draft action Discard;
draft determine action Prepare
{
validation validateKeyIsFilled;
validation validateCoreData;
}
Neue Verhaltensdefinition
Die neue Verhaltensdefinition sieht nach den ganzen Anpassungen nun wie folgt aus:
managed implementation in class zbp_bs_demo_rappartner unique;
strict;
with draft;
define behavior for ZBS_I_RAPPartner alias Partner
persistent table zbs_dmo_partner
draft table zbs_dmo_dpartner
lock master total etag LastChangedAt
authorization master ( instance )
late numbering
etag master LastChangedAt
{
create;
update;
delete ( features : global );
field ( readonly ) PartnerNumber;
draft action Resume;
draft action Edit;
draft action Activate;
draft action Discard;
draft determine action Prepare
{
validation validateKeyIsFilled;
validation validateCoreData;
}
validation validateKeyIsFilled on save { create; }
validation validateCoreData on save { create; field Country, PaymentCurrency; }
determination fillCurrency on modify { create; update; }
static action withPopup parameter ZBS_I_PopupEntity;
action ( features : instance ) fillEmptyStreets result [1] $self;
static action clearAllEmptyStreets;
factory action copyLine [1];
mapping for zbs_dmo_partner
{
PartnerNumber = partner;
PartnerName = name;
Street = street;
City = city;
Country = country;
PaymentCurrency = payment_currency;
LastChangedAt = last_changed_at;
}
}
Projektion
Damit der Draft auch über die App verfügbar ist, muss dieser in der Projektion der Verhaltensdefinition auch nach außen gegeben werden. Dazu wird bekannt gegeben, dass Darft verwendet wird und die verschiedenen Aktionen werden freigegeben. Nach Anpassung sieht die Projektion nun wie folgt aus:
projection;
strict;
use draft;
define behavior for ZBS_C_RAPPartner alias Partner
{
use create;
use update;
use delete;
use action fillEmptyStreets;
use action clearAllEmptyStreets;
use action copyLine;
use action withPopup;
use action Edit;
use action Activate;
use action Discard;
use action Prepare;
use action Resume;
}
Verhalten
Was hat sich nun eigentlich an der App geändert und was bringt es nun? Sobald wir die App öffnen, fällt auf, dass nun in der Filterleiste eine weitere Option hinzugekommen ist:
Damit können die verschiedenen Drafts selektiert oder du kannst dir nur die "echten" Datensätze filtern. Dieser Filter wird dir automatisch mit dem Draft Handling geschenkt. Im nächsten Schritt schauen wir uns einmal das Detailbild eines Datensatzes an:
Dabei fällt auf, dass es nun einige Buttons mehr gibt, die uns einige Zusatzfunktionen zur Verfügung stellen:
- Display Saved Version - Anzeige der Originalversion des Datensatzes, wenn bereits Änderungen durchgeführt wurden.
- Discard Draft - Der Draft wird aus der Draft Tabelle entfernt und der originale Datensatz ist der führende und einzige Datensatz.
Sobald du nun eine Änderung an einem Feld durchführst und den Fokus auf ein anderes Feld wechselst, wird ein Draft auf der Datenbank angelegt und die Informationen gesichert:
Beim Klick auf den "Save" Button wird der Datensatz aus der Draft Tabelle als neue aktive Version übernehmen. Wenn du allerdings einfach zurück gehen möchtest, dann wirst du gefragt, was du nun tun möchtest:
Setzen wir den Punkt "Keep Draft" dann wird der Zwischenstand weiterhin gesichert und wir landen wieder auf dem Übersichtsbild. Wenn wir nun den Filter entsprechend auf unsere eigenen Einträge setzen, dann wird unser geänderter Datensatz angezeigt:
Fazit
Du weißt nun, wie man den Draft im Business Objekt aktiviert und nutzt. Weiterhin weißt du, welche Voraussetzungen eine Tabelle mitbringen muss, damit Draft auch aktiviert werden kann. Die Funktion gibt es in vielen Standardapps und sie vollendet das Benutzererlebnis im Fiori Kontext.