Skip to main content
Skip table of contents

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:

YAML
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:

YAML
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:

JSON
{
	"@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:

JSON
{
	"@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:

YAML
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:

CODE
| 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:

YAML
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.
Der Name muss mit einem Großbuchstaben beginnen und darf Buchstaben, Zahlen und Unterstriche _ beinhalten. Außerdem muss der Name mit dem Package-Key beginnen.

type

Typ der Entität

  • dbTable

  • dbView

source?

(optional) - Quelle der Entität

  • be

  • beng

Standardwert: beng

managed?

(optional) - Falls true wird die physische Entität als Tabelle in der Datenbank angelegt und verwaltet. Änderungen an Feldern oder Indizes werden automatisch beim Laden des Packages in die Datenbank übernommen.

Standardwert: true

schemaName?

(optional) - PostgreSQL-Schema, in dem sich die Tabelle der physischen Entität befindet.

  • data

  • custom

Standardwert: data

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 _ beinhalten.

Standardmäßig wird der entityName in snake_case_schreibweise benutzt.

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 fields definiert werden.

Standardwert: ID

workarea?

(optional) - Workarea der be Tabelle.

Standardwert: -1

locationFilter?

(optional) - Gibt an, ob die Werte der Entität von einem oder mehreren Standort(en) abhängig sind.

  • fixed: Die Werte der Entität sind von einem Standort abhängig

  • selection: Die Werte der Entität können von mehreren Standorten abhängig sein.

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.

Entitäten | Eigenschaften-von-dependsOn

fields

Liste der Felder, die zur Entität gehören. Die Felder müssen in der Tabelle/View existieren.

Entitäten | Eigenschaften-von-fields

indices?

(optional) - Liste der Indizes, die auf der Tabelle definiert sind.

Entitäten | Eigenschaften-von-indices

permissions?

(optional) - Berechtigungen für Entitäten. Mit statischen SQL Filtern und dynamischem JavaScript.

Entitäten | Eigenschaften-von-permissions

viewDefinition?

(optional) - SQL Query für die Definition des Views, welche die Datengrundlage der Entität ist.

Entitäten | Eigenschaften-von-viewDefinition

businessLogic?

(optional) - Fachliche Logik für Entitäten.

Entitäten | Eigenschaften-von-businessLogic

groups?

(optional) - Liste. Aufbau einer Standard-Oberfläche, die über ein entityContainer-Control verwendet werden kann. Die Gruppen werden in der Reihenfolge angezeigt, wie sie hier definiert sind.

Entitäten | Eigenschaften-von-groups

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 benutzen)

beTableName?

(optional) - Name der Tabelle, welche die Datengrundlage für die Entität ist.

fieldName?

(optional) - Name des Feldes.

(deprecated, bitte beTableFieldName benutzen)

beTableFieldName?

(optional) - Name des Feldes.

isPrimaryKey?

(optional) - Gibt an, ob das Feld der Primary-Key ist.

(deprecated, bitte isBeTablePrimaryKey benutzen)

isBeTablePrimaryKey?

(optional) - Gibt an, ob das Feld der Primary-Key ist.

isNullable?

(optional) - Falls true, kann das Feld NULL enthalten.

Standardwert: true

defaultValue?

(optional) - Default-Wert des Feldes. Es kann ein Wert wie z.B. 0.0 oder 'DEFAULT' angegeben werden oder ein gültiger PostgreSQL Ausdruck, wie z.B. NOW() oder uuid_generate_v4().

visibleInList?

(optional) - Falls true, ist dieses Feld sichtbar in der Liste der Stammdaten.

visibleInDetails?

(optional) - Falls true, ist dieses Feld sichtbar in der Detailansicht des Stammdaten-Datensatz.

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 . getrennt.

deprecated?

(optional) - Falls true, gilt das Feld als veraltet. Veraltete Felder werden gelöscht.

Standardwert: false

inherited?

(optional) - Name des Feldes, von dem abgeleitet wird. Der Entitätsname muss als Präfix vorangestellt werden. Zum Beispiel: C_HEWO_Articles.artnr

gui?

(optional) - Definition von Standards, die für den Oberflächenaufbau herangezogen werden.

Entitäten | Eigenschaften-von-gui

dbType?

(optional) - Typ des Feldes bzw. Name eines PostgreSQL-Enums bestehend aus <PACKAGE_KEY>_>Enum-Name>.

  • uuid

  • text

  • character

  • varchar

  • boolean

  • shortint

  • integer

  • bigint

  • smallint

  • double precision

  • numeric

  • date

  • time

  • timestamp

  • serial

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.

  • string

  • number

  • date

  • datetime

  • time

  • boolean

  • object

  • amount

  • entityLink

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 type = EntityLink verknüpft werden soll. Die Variable name wird als Schlüssel verwendet und verweist auf den Tabellennamen. Zur Definition von Lookupfeldern oder im Falle von aktivierter Editierbarkeit Auswahlmöglichkeit durch EntityLinks.

Entitäten | Eigenschaften-von-entity

grid?

(optional) - Definition von Standards für die Anzeige in einem entityGrid. Hier können dieselben Eigenschaften angegeben werden, die unter gui verfügbar sind.

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 displayValue im Elternelement Zugriff auf die Zeile des entityGrids hat, hat dieser displayValue Zugriff auf die verknüpfe Entity.

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 fields definiert ist oder ein Ausdruck, der in SQL verwendet werden kann.

Damit ein Ausdruck verwendet werden kann, muss das Feld expression definiert sein.

Ausdrücke sollten genauso definiert werden, wie auch PostgreSQL sie anlegt, damit keine unnötigen DDL Operationen durchgeführt werden.

Entitäten | Eigenschaften-von-columns

isUnique?

(optional) - Falls true, ist der Index ein Unique-Index.

Standardwert: false

Eigenschaften von columns

name

Name des Feldes.

expression

SQL Ausdruck, der Teil des Index ist.
Dieser Ausdruck sollte jedoch so definiert werden, wie ihn auch PostgreSQL anlegt, damit keine unnötigen DDL Operationen durchgeführt werden.

LEFT(aufnr, 6) wird zu "left"(aufnr, 6) in PostgreSQL.
Da die definierten Feldnamen im PostgreSQL ggf. anders geschrieben werden, kann in Expression {{<FieldName>:columnName}} verwendet werden, um den richtigen Feldnamen für den Index zu verwenden.

Zum Beispiel:
Feld: artikelNummer wird in PostgreSQL zu artikel_nummer
Index-Expression: LEFT({{artikelNummer:columnName}}, 6) wird zu LEFT(artikel_nummer, 6) in PostgreSQL.

order?

(optional) - Sortierung des Feldes.

Standardwert: ASC

nulls?

(optional) - Sortierung von NULL Werten.

FIRST bedeutet, dass NULL Werte vor den anderen Werten sortiert werden.
LAST bedeutet, dass NULL Werte nach den anderen Werten sortiert werden.
Defaults:

  • Wenn die Sortierung DESC ist, ist der Default NULLS FIRST.

  • Wenn die Sortierung nicht DESC ist, ist der Default NULLS LAST.

Eigenschaften von permissions

read?

(optional) - Liste der Rollen, die Lese-Rechte auf die Entität haben.

Entitäten | Eigenschaften-von-read

update?

(optional) - Liste der Rollen, die Update-Rechte auf die Entität haben.

Entitäten | Eigenschaften-von-update/create/delete

create?

(optional) - Liste der Rollen, die Anlage-Rechte auf die Entität haben.

Entitäten | Eigenschaften-von-update/create/delete

delete?

(optional) - Liste der Rollen, die Lösch-Rechte auf die Entität haben.

Entitäten | Eigenschaften-von-update/create/delete

Eigenschaften von read

role

Bezeichnung der Rolle. Es sind alle Rollen des zugehörigen Packages und die BE-Rollen erlaubt: BE.admin, BE.portalUser, BE.internalUser, BE.workflowUser

filter?

(optional) - SQL konformer Filter, z.B. dab000.kdnr > 50000. Kann auch per Expression definiert werden.

Eigenschaften von update/create/delete

role

Bezeichnung der Rolle. Es sind alle Rollen des zugehörigen Packages und die BE-Rollen erlaubt: BE.admin, BE.portalUser, BE.internalUser, BE.workflowUser

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.

  • vertical: Elemente werden untereinander angeordnet.

  • horizontal: Elemente werden nebeneinander angeordnet.

size?

(optional) - Gibt die Breite an.

  • small

  • normal

  • large

  • full

  • auto

type

Control-Typ auf der Oberfläche.

  • container

  • tabContainer

  • tab

groups?

(optional) - Liste der Untergruppen, die in dieser Gruppe angezeigt werden.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.