Entitäten
Was sind Entitäten?
Eine Entität ist eine einzelne, eindeutig identifizierbare Instanz eines Datentyps. Grundlage für die Bereitstellung von Daten sind PostgreSQL, ADS oder Berechnungen zur Laufzeit. Über das Anwendungsframework können diese Datentypen (oder ugs.: Entitäten) individuell erstellt werden.
Entitätskategorien
In diesem Abschnitt werden die verschiedenen Entitätskategorien erläutert, die mithilfe des Anwendungsframeworks definiert werden können.
Physische Entitäten
Aus der Definition wird beim Laden des Packages eine Datenbanktabelle in der PostgreSQL-Datenbank erstellt. Alle definierten Indizes sowie Felder werden angelegt und bei Änderungen aktualisiert.
Folgende Standardfelder werden automatisch angelegt:
uuid
version
createdAt
createdBy
updatedAt
updatedBy
Beispiel einer physischen Entität:
entityName: PKGKEY_MyEntity
primaryKeyName: uuid
type: dbTable
source: beng
managed: true
permissions:
read:
- role: PKGKEY.user
create:
- role: PKGKEY.admin
# Das Feld `userName` wird in der Tabelle zu `user_name`.
# Der Index muss die Feldnamen der Tabelle verwenden.
indices:
- name: user_name
isUnique: true
columns:
- name: "{{userName:columnName}}"
order: DESC
- expression: LEFT({{userName:columnName}}, 10)
order: DESC
nulls: FIRST
fields:
- name: age
label: Alter
dbType: integer
isNullable: false
defaultValue: 18
- name: userName
label: Benutzername
dbType: text
- name: mySpaceId
label: mySpace
deprecated: true
Standardwerte und Index-Ausdrücke können in der PostgreSQL-Datenbank unter Umständen anders aussehen als im Package angegeben.
Dadurch kann es zu unnötigen Updates der Tabelle/des Index beim Neuladen des Packages kommen. In solchen Fällen muss per pgAdmin untersucht werden, woher der Unterschied kommt, damit es im Package angeglichen werden kann.
View-Entitäten
View-Entitäten werden zur lesenden Bereitstellung von Daten eingesetzt.
Folgendes Beispiel definiert eine Entität PKGKEY_ArbeitsZeitArtikel
. Die Datengrundlage ist eine View, welche alle Arbeitszeit-Artikel beinhaltet und nur wenige Felder der Dab010
enthält.
Beispielhafte YAML-Definition:
entityName: PKGKEY_ArbeitsZeitArtikel
primaryKeyName: id
type: dbView
viewDefinition:
pgSql: |
SELECT id, matchcode, artnr, arttyp
FROM data.dab010
WHERE arttyp = 'A'
fields:
- name: id
label: ID
dbType: integer
- name: matchcode
label: Matchcode
dbType: character
- name: artnr
label: Artikelnummer
dbType: character
- name: arttyp
label: Artikeltyp
dbType: character
dbLength: 1
permissions:
read:
- role: admin
- role: user
filter: dab010.arttyp = 'A'
create:
- role: admin
update:
- role: admin
- role: user
delete:
- role: admin
Über die Eigenschaft permissions
wird gesteuert, welche Rolle benötigt wird, um die gegebene Aktion auszuführen. Ohne Rollenangabe ist die Aktion nur für Benutzer mit der Rolle admin
des definierenden Packages ausführbar.
Pro Rolle kann außerdem ein statischer SQL Filter angegeben werden. Sobald einer der Berichtigungsfilter zutrifft, ist der Zugriff auf die Daten gegeben. Beim Ändern und Löschen von Daten muss sowohl die entsprechende Berechtigung als auch die Leseberechtigung gegeben sein.
Beispielabruf von Entitäten
Eine Entität (“einzelner Datensatz”), die über die OData-Schnittstelle abgerufen wird, sieht zum Beispiel so aus:
{
"@odata.context": "http://<tenant>.businessexpress.cloud/odata/v4/$metadata#PKGKEY_ArbeitsZeitArtikel/$entity",
"id": 40,
"matchcode": "A_ZUSCHNEIDEN",
"artnr": "A_ZUSCHNEIDEN",
"arttyp": "A"
}
… und eine EntityCollection (“mehrere Datensätze”) so:
{
"@odata.context": "http://<tenant>.businessexpress.cloud/odata/v4/$metadata#ArbeitsZeitArtikel",
"value": [
{
"id": 71,
"matchcode": "A_DREHEN_KLEIN",
"artnr": "A_DREHEN_KLEIN",
"arttyp": "A"
},
{
"id": 73,
"matchcode": "A_DREHEN_GROSS",
"artnr": "A_DREHEN_GROSS",
"arttyp": "A"
},
{
"id": 126,
"matchcode": "A_DREHEN_GROSS",
"artnr": "A_DREHEN_GROSS",
"arttyp": "A"
},
{
"id": 127,
"matchcode": "A_DREHEN_KLEIN",
"artnr": "A_DREHEN_KLEIN",
"arttyp": "A"
}
]
}
View-Entitäten mit Bearbeitung in Codeblock
Datenbanktabellen, die hoheitlich in der ADS-Datenbank gepflegt und in die PostgreSQL-Datenbank repliziert werden (sog. “be-Tabellen”), können nicht direkt in der PostgreSQL-Datenbank bearbeitet werden.
Um dennoch ADS-Daten per Entität sowohl lesen als auch bearbeiten zu können, können View-Entitäten mit Bearbeitung in Codeblock erstellt werden.
Grundlage ist die Definition einer normalen View-Entität. Daher erfolgt der lesende Zugriff über die in der PostgreSQL-Datenbank replizierte Tabelle.
Durch den Parameter source: be
wird gesteuert, dass diese Entität bearbeitet werden kann und hierfür ein entsprechendes Codeblock-Programm existiert. Das Codeblock-Programm definiert Funktionen für den Umgang mit Schreib-/Löschanfragen (siehe unten).
Folgendes Beispiel definiert die Entität PKGKEY_Artikelgruppen
. Die Datengrundlage ist eine View, welche alle Artikelgruppen beinhaltet und nur wenige Felder der Dab310
enthält.
Beispielhafte YAML-Definition:
entityName: PKGKEY_Artikelgruppen
type: dbView
source: be
primaryKeyName: id
permissions:
read:
- role: admin
update:
- role: admin
create:
- role: admin
delete:
- role: admin
fields:
- name: id
dbType: integer
label: ID
tableName: Dab310
isPrimaryKey: true
- name: group_number
dbType: text
label: Artikel-Gruppe-Nr.
tableName: Dab310
- name: bez1
dbType: text
label: Bezeichnung
tableName: Dab310
viewDefinition:
pgSql: |
SELECT
id,
artgruppe as group_number,
bez1
FROM data.dab310
Bei einem GET
-Request werden die Daten wie bei https://dontenwill.atlassian.net/wiki/spaces/BPOH/pages/edit-v2/38666303#Views aus einer Datenbank-View gelesen.
Die Methoden POST
, PATCH
und DELETE
werden im Codeblock bearbeitet.
Es werden entsprechend die Funktionen POST
, PATCH
und DELETE
im Programm mit dem Schema <packageBasisOrdner>\.customizing\.entityHandler\<tableName>
aufgerufen.
Bei diesem Beispiel könnte das Codeblock-Programm wie folgt aussehen:
| oDM:P1, oHeaders:P2 |
//******************************************************************************
// Implementierung für die HTTP-Methode POST (Neuanlage eines Datensatzes)
// @Result: null
//******************************************************************************
function POST(oBody)
| oDab310 |
case Upper(oHeaders.getString('entity-name'))
of 'PKGKEY_ARTIKELGRUPPEN' ::
oDab310 := DBGetTable(oDM, waDab310),
oDab310.CbInsert(),
oDab310:ARTGRUPPE := oBody.getString('group_number'),
oDab310:BEZ1 := oBody.getString('bez1'),
oDab310.CbPost(),
otherwise
SetError('no implementation for entity ' + oHeaders.getString('entity-name')),
endcase,
end,
//******************************************************************************
// Implementierung für die HTTP-Methode PATCH (Aktualisierung eines Datensatzes)
// @Result: null
//******************************************************************************
function PATCH(uIdentifier, oBody)
| oDab310 |
case Upper(oHeaders.getString('entity-name'))
of 'PKGKEY_ARTIKELGRUPPEN' ::
oDab310 := DBGetTable(oDM, waDab310),
oDab310.CbIndexName := 'ID',
if (oDab310.CbFindKey({uIdentifier})) then
oDab310.CbEdit(),
oDab310:BEZ1 := oBody.getString('bez1'),
oDab310.CbPost(),
else
SetError('record with id ' + uIdentifier + ' not found'),
endif,
otherwise
SetError('no implementation for entity ' + oHeaders.getString('entity-name')),
endcase,
end,
//******************************************************************************
// Implementierung für die HTTP-Methode DELETE (Löschen eines Datensatzes)
// @Result: null
//******************************************************************************
function DELETE(uIdentifier)
| oDab310 |
case Upper(oHeaders.getString('entity-name'))
of 'PKGKEY_ARTIKELGRUPPEN' ::
oDab310 := MyGetTable(oDM, waDab310),
oDab310.CbIndexName := 'ID',
if (oDab310.CbFindKey({uIdentifier})) then
MyDelete(oDab310),
else
SetError('record with id ' + uIdentifier + ' not found'),
endif,
otherwise
SetError('no implementation for entity ' + oHeaders.getString('entity-name')),
endcase,
end,
Entitätsdefinition (YAML-Eigenschaften)
Entitäten werden entweder direkt in der be_package.yaml
-Datei oder in separaten Dateien nach dem Namensschema <packageFolder>/.objects/<name>.entities.yaml
definiert. Aus Übersichtlichkeitsgründen wird die Definition von Entitäten in separaten Dateien empfohlen. Es kann immer eine Liste von mehreren Entitätsdefinitionen wie folgt angegeben werden:
entities:
- entityName: entity1
type: dbView
...
- entityName: entity2
type: dbTable
...
...
Folgende Eigenschaften können bei Entitäten definiert werden.
entityName | Name der Entität. Dieser Name wird in der OData-Schnittstelle verwendet, um mit der Entität zu interagieren. |
---|---|
type | Typ der Entität
|
source? | (optional) - Quelle der Entität
Standardwert: |
managed? | (optional) - Falls Standardwert: |
schemaName? | (optional) - PostgreSQL-Schema, in dem sich die Tabelle der physischen Entität befindet.
Standardwert: |
tableName? | (optional) - Name der Tabelle, welche die Datengrundlage für die Entität ist. Der Name muss kleingeschrieben werden und darf Buchstaben, Zahlen und Unterstriche Standardmäßig wird der |
fibuTableName? | (optional) - Fibu-Name der Tabelle, welche die Datengrundlage für die Entität ist. |
primaryKeyName? | (optional) - Name des Primary-Key Feldes. Das Primary-Key Feld muss in Standardwert: |
workarea? | (optional) - Workarea der be Tabelle. Standardwert: |
locationFilter? | (optional) - Gibt an, ob die Werte der Entität von einem oder mehreren Standort(en) abhängig sind.
|
dependsOn? | (optional) - Liste der Entitäten, von denen diese Entität abhängt. Diese hier angegebenen Entitäten müssen in der gleichen Package-Definition definiert sein. |
fields | Liste der Felder, die zur Entität gehören. Die Felder müssen in der Tabelle/View existieren. |
indices? | (optional) - Liste der Indizes, die auf der Tabelle definiert sind. |
permissions? | (optional) - Berechtigungen für Entitäten. Mit statischen SQL Filtern und dynamischem JavaScript. |
viewDefinition? | (optional) - SQL Query für die Definition des Views, welche die Datengrundlage der Entität ist. |
businessLogic? | (optional) - Fachliche Logik für Entitäten. |
groups? | (optional) - Liste. Aufbau einer Standard-Oberfläche, die über ein |
label? | (optional) - Nutzen unbekannt |
Eigenschaften von dependsOn
entity | Name der Entität. |
---|
Eigenschaften von fields
name | Name des Feldes. Maximal 30 Zeichen. |
---|---|
label? | (optional) - Anzeige-Name des Feldes. Standardwert: |
tableName? | (optional) - Name der Tabelle, welche die Datengrundlage für die Entität ist. (deprecated, bitte |
beTableName? | (optional) - Name der Tabelle, welche die Datengrundlage für die Entität ist. |
fieldName? | (optional) - Name des Feldes. (deprecated, bitte |
beTableFieldName? | (optional) - Name des Feldes. |
isPrimaryKey? | (optional) - Gibt an, ob das Feld der Primary-Key ist. (deprecated, bitte |
isBeTablePrimaryKey? | (optional) - Gibt an, ob das Feld der Primary-Key ist. |
isNullable? | (optional) - Falls Standardwert: |
defaultValue? | (optional) - Default-Wert des Feldes. Es kann ein Wert wie z.B. |
visibleInList? | (optional) - Falls |
visibleInDetails? | (optional) - Falls |
group? | (optional) - Gruppe, in der das Feld angezeigt wird. Der Gruppenname setzt sich aus dem Namen der Gruppe und dem Namen der Tabkarte zusammen. Diese Gruppennamen werden mit einem Punkt |
deprecated? | (optional) - Falls Standardwert: |
inherited? | (optional) - Name des Feldes, von dem abgeleitet wird. Der Entitätsname muss als Präfix vorangestellt werden. Zum Beispiel: |
gui? | (optional) - Definition von Standards, die für den Oberflächenaufbau herangezogen werden. |
dbType? | (optional) - Typ des Feldes bzw. Name eines PostgreSQL-Enums bestehend aus <PACKAGE_KEY>_>Enum-Name>.
|
dbLength? | (optional) - Länge des Feldes (zwischen 1 und 255). |
specification? | (optional) - Name einer Feld-Spezifikation bestehend aus <PACKAGE_KEY>.<Specification_Name>. |
Eigenschaften von gui
label? | (optional) - Label des Feldes. |
---|---|
type? | (optional) - Anzeigetyp.
|
highlight? | (optional) - Hervorhebungsstil. |
searchable? | (optional) - Angabe, ob das Feld durchsuchbar sein soll. |
sortable? | (optional) - Angabe, ob das Feld sortierbar sein soll. |
width? | (optional) - Angabe der Breite als Anzahl in Pixeln oder als CSS-valide Breitenangabe (z.B. 10%). |
visible? | (optional) - Steuerung der Feldsichtbarkeit. |
defaultFocus? | (optional) - Angabe, ob das Feld standardmäßig im Fokus stehen soll. |
alignment? | (optional) - Definiert die Ausrichtung des Spaltentextes. |
displayValue? | (optional) - Möglichkeit zur Bestimmung eines abweichenden Anzeigetextes. |
entity? | (optional) - Angaben zur Entität, die bei |
grid? | (optional) - Definition von Standards für die Anzeige in einem |
Eigenschaften von entity
displayValue? | (optional) - Definiert die Anzeige des Wertes in der Tabelle. Der Wert kann entweder statisch oder ein gültiger Javascript-Code sein, der ein boolsches Ergebnis zurück liefert. Während |
---|---|
name | Name der Entität. |
columnDefinition? | (optional) - Optionale Definition von Spalten. Standardmäßig werden alle sichtbaren Felder der Entität angezeigt. Hier können einzelne Spalten weiter definiert werden. |
Eigenschaften von indices
name | Name des Index. Maximal 63 Zeichen lang. |
---|---|
columns | Liste der Felder, die Teil des Index sind. Es kann entweder der Name eines Feldes sein, der auch in Damit ein Ausdruck verwendet werden kann, muss das Feld Ausdrücke sollten genauso definiert werden, wie auch PostgreSQL sie anlegt, damit keine unnötigen DDL Operationen durchgeführt werden. |
isUnique? | (optional) - Falls Standardwert: |
Eigenschaften von columns
name | Name des Feldes. |
---|---|
expression | SQL Ausdruck, der Teil des Index ist.
Zum Beispiel: |
order? | (optional) - Sortierung des Feldes. Standardwert: |
nulls? | (optional) - Sortierung von FIRST bedeutet, dass
|
Eigenschaften von permissions
read? | (optional) - Liste der Rollen, die Lese-Rechte auf die Entität haben. |
---|---|
update? | (optional) - Liste der Rollen, die Update-Rechte auf die Entität haben. |
create? | (optional) - Liste der Rollen, die Anlage-Rechte auf die Entität haben. |
delete? | (optional) - Liste der Rollen, die Lösch-Rechte auf die Entität haben. |
Eigenschaften von read
role | Bezeichnung der Rolle. Es sind alle Rollen des zugehörigen Packages und die BE-Rollen erlaubt: |
---|---|
filter? | (optional) - SQL konformer Filter, z.B. |
Eigenschaften von update
/create
/delete
role | Bezeichnung der Rolle. Es sind alle Rollen des zugehörigen Packages und die BE-Rollen erlaubt: |
---|---|
sql? | (optional) - SQL konforme Filterbedingung, die zum Schreiben berechtigt. |
script? | (optional) - JavaScript Ausdruck. Siehe auch Entitätsberechtigungen |
Eigenschaften von viewDefinition
pgSql | PostgreSQL-Query |
---|
Eigenschaften von businessLogic
filter | Basisfilter der Entität, damit z.B. nur Artikel einer bestimmten Art oder nur die eigenen Datensätze teil der Entität sind. |
---|
Eigenschaften von groups
name | Basisfilter der Entität, damit z.B. nur Artikel einer bestimmten Art oder nur die eigenen Datensätze teil der Entität sind. |
---|---|
collapsible? | (optional) - Definiert, ob der Container einklappbar ist. |
label? | (optional) - Caption der Gruppe oder Label der Tabkarte. |
flow? | (optional) - Definiert die Ausrichtung des Elements.
|
size? | (optional) - Gibt die Breite an.
|
type | Control-Typ auf der Oberfläche.
|
groups? | (optional) - Liste der Untergruppen, die in dieser Gruppe angezeigt werden. |