Versionen im Vergleich

Schlüssel

  • Diese Zeile wurde hinzugefügt.
  • Diese Zeile wurde entfernt.
  • Formatierung wurde geändert.
Auszug
hiddentrue

Nuclos clientseitige Regeln: Groovy-Berechnungsausdrücke, context-Zugriff, dynamische Eigenschaften (aktiv/inaktiv), Bibliotheksfunktionen, Debugging.

globe with meridians Sprache: Deutsch · English

open book Regeln (clientseitig)

Groovy direkt in der Maske: berechnete Werte, dynamische Feld-/Button-Zustände und Funktionen über den context.

Status
colourGrey
titleReferenz
Status
colourBlue
titleLow-Code
Status
colourGreen
titleStand: Jul 2026
Status
colourGrey
titlegilt fuer Nuclos 4.2026.x

Panel
bgColor#F4F5F7

Auf dieser Seite

Inhalt
maxLevel2
minLevel

...

Definition

Mit clientseitigen Regel können dynamisch im Layout oder auch über das BO Groovy-Regeln hinterlegt werden. 

2

Was sind clientseitige Regeln?

Clientseitige Regeln sind Groovy-Ausdrücke, die direkt in der Maske reagieren – für berechnete Werte, dynamische Eigenschaften (z. B. Feld aktiv/inaktiv, Hintergrundfarbe) und Buttons. Sie werden am Layout oder am Businessobjekt hinterlegt.

...

Namensräume und Packages

Ein Namensraum wird pro Nuclet definiert

...

(lokaler Identifizierer). Businessobjekte ohne Nuclet nutzen den Default-Namespace DEF. Packages ermöglichen Spring-managed Bibliotheksregeln (aufrufbare Funktionen).

Beispiel Berechnete Werte 

Dynamische Eigenschaften (z.B. Hintergrundfarbe von Zeilendarstellungen) und berechnete Werte (z.B. Berechnungsausdruck bei Attributen) können in Groovy-Code definiert werden.

Clientregeln für berechnete Werte werden immer auf dem Zielfeld definiert. Im Businessobjekt findet sich in der Attributdefinition ein Button 'Berechnungsausdruck'. Hier wird der Groovy-Code hinterlegt.

ApplicationProgrammingInterface 1.jpgImage Removed

Sie können im Code über die Variable "context" und passende Ausdrücke (im Code: context."Ausdruck" auf die Kontextinformationen und Daten des Objekts zugreifen.

Folgende Ausdrücke werden im Moment unterstützt:

(Info) [entity] steht dabei für den internen Namen des Businessobjekts wie er im BO-Editor angegen ist (nicht der Anzaigename oder Tabellenname).

Referenzierte Kontexte

Häufig wird ein Zugriff auf Werte eines referenzierten Objekts benötigt. Hierfür kann der Ausdruck #{[namespace].[entity].[field].context} verwendet werden. Dieser Ausdruck liefert ein neues Context-Objekt, mit dem Sie in identischer Weise weiterarbeiten können. Zu beachten ist, dass ein referenzierter Kontext häufig nur eingeschränkte Daten liefert. Bei Auswahlfeldern stehen z.B. nur die Werte des referenzierten Datensatzes zur Verfügung - ein erneuter Aufruf von #{[namespace].[entity]} oder #{[namespace].[entity].[field].context} ist also nicht möglich.

Zugriff über context

Im Code greifst du über die Variable context und Ausdrücke auf Daten zu. [entity] ist der interne Name des Businessobjekts:

Codeblock
languagegroovy

...

#{[namespace].[entity]}     

...

 

...

 

...

 

...

 

...

 

...

// 

...

aktuelles 

...

BO 

...

/ 

...

Unterformular-Datensätze als Liste
#{[namespace].[entity].[field]}  //

...

 Wert eines Attributs

...


#{[namespace].[entity].[field].

...

id} 

...

 

...

 

...

 

...

 

...

 //

...

 Id

...

 eines Referenzfelds 

...

(java.lang.Long)
#{[namespace].[entity].[field].context} // 

...

Context 

...

eines 

...

referenzierten 

...

Objekts

Auswertung des Scripts

Das Script wird ausgeführt, wenn

...

ein neuer Datensatz

...

angelegt wird

...

oder sich ein ausgelesenes Feld ändert

...

Beispiel

Hier ein Beispiel für die Berechnung eines Gesamtbetrages. Der Gesamtbetrag wird durch Iteration über ein Unterformular 'auftrag_position' ermittelt.

. Beispiel – Gesamtbetrag über ein Unterformular summieren:

Codeblock
languagegroovy
def brutto

...

 = new java.math.BigDecimal(0.000)

...

context."#{WAR.auftrag

...

_position}".each {

...

 item ->
  

...

 

...

 

...

brutto = 

...

brutto.add(java.math.BigDecimal.valueOf(
        item."#{WAR.auftrag_position.gesamtpreisrechnung}"

...

)

...

)

...

}
return 

...

brutto.setScale(4, java.math.RoundingMode.HALF_UP).doubleValue(

...

)

Dynamische Eigenschaften (aktiv/inaktiv)

Über einen booleschen Rückgabewert steuerst du „Bearbeiten/Neu/Löschen/Klonen

...

Bearbeiten aktiv (dynamisch)

Die Aktivierung/Deaktivierung der Spalten wird entsprechend eines boolschen Rückgabewertes durchgeführt.

aktiv“ sowie Buttons: return true =

...

aktiv

...

, return false =

...

inaktiv.

...

Warnung
titleKontext beachten

Der Ausgangskontext für

...

Neu aktiv

...

ist

...

das übergeordnete BO der Subform,

...

für

...

Will man sich also beispielsweise in einem Subform für Auftragspositionen den Status des Auftrages holen, muss man dies für "Neu" mittels

context."#{NAME.Auftrag.nuclosStateNumber}"

...

Bearbeiten/Löschen/Klonen aktiv hingegen das Subform-BO selbst. Für den Status des Auftrags aus einer Position: erst einen Kontext nach oben gehen

...

context."#{NAME.Auftragsposition.auftrag.context}"."#{NAME.Auftrag.nuclosStateNumber}".

Verwendung 1

Bestimmte Felder sollen abhängig des ausgewählten Wertes (componentType) aktiviert oder deaktiviert sein.

Verwendung 2

Feld invoiceamountinhours soll abhängig des ausgewählten Wertes (chargedashours) aktiviert oder deaktiviert sein.

Vorsicht: Da im Namen des BO ein Leerzeichen enthalten ist, muss es auch im Groovy-Code so angesprochen werden ("External services").

Funktionen über Bibliotheksregeln 

Sie können in Bibliotheksregeln Funktionen definieren, die in dynamischen Eigenschaften und berechneten Werten verwendet werden können. Eine Bibliotheksregel muss hierfür mit der Annotation org.springframework.stereotype.Component gekennzeichnet werden, damit sie von der Laufzeitumgebung erkannt wird (Hinweis: es wird nur eine Instanz der Klasse erzeugt - beachten Sie dies beim Einsatz von Klassenvariablen). Falls Sie eine Methode dieser Klasse als Funktion verwenden möchten, kennzeichnen Sie diese mit der Annotation org.nuclos.api.annotation.Function und vergeben Sie einen global eindeutigen Namen. Diesen Namen verwenden Sie später, um die Funktion mit Hilfe über context."#FUNCTION{<Funktionsname>}" aufzurufen. Bei der Implementierung von Funktionen ist darauf zu achten, dass Parameter- und Rückgabe-Typen übereinstimmen. Ggf. notwendige Umwandlungen müssen manuell vorgenommen werden. Ausserdem muss beachtet werden, dass der Namensraum des Packages im Nuclet Mangagement und der Packagename der Componente (Bibliotheksregel) gleich sind.

Verwendung 3

In folgendem Beispiel wird eine automatische Vergabe von Bestellnummern in Abhängigkeit des ausgewählten Kunden implementiert.

 Bibliotheksregel mit Funktion

Dynamisch berechneter Wert

context."#FUNCTION{org.nuclet.rules.MyFunction}"(context."#{DEF.Kunde.kundennr}")

(.context).

Funktionen über Bibliotheksregeln

Eine Bibliotheksregel mit @Component (Spring) und einer mit @Function("name") annotierten Methode lässt sich per context."#FUNCTION{name}"(...) aufrufen. Namensraum des Packages und Packagename müssen übereinstimmen; Parameter-/Rückgabetypen müssen passen.

Best Practices & Debugging

Feld aus dem Elternobjekt lesen (Feld muss im Layout vorhanden, ggf. deaktiviert sein)

Logausgaben

Um Clientregeln zu debuggen, können Logausgaben eingegeben werden:

    log.info("Logausgabe")

Die Ausgabe kann in der Scripting-Ausgabe (Fenster / Ausgabe (Scripting)) eingesehen werden.

Ausgabe aktueller User

Aktueller User (Nuclos Version 4.0.15 und höher)

Die Variable username kann in Groovy Skripten verwendet werden.

In dieser Variable vom Typ java.lang.String steht der aktuelle User.

z.B.: def anwender = username

Der aktuelle User wird in die Variable anwender übertragen.

Aktivierung/Deaktivierung von Buttons im Layout

Die Aktivierung/Deaktivierung der Buttons wird entsprechend eines boolschen Rückgabewertes durchgeführt.

  • return true = Button aktiv

  • return false = Button nicht aktiv

 Known Issues- Best Practice

Feld aus Elternbusinessobjekt / Hauptbusinessobjekt auslesen

Codeblock
languagegroovy
fieldFromParent = context."#{<NUCLET>.<SUBENTITY>.<REFERENCEFIELD>.context}"."#{<NUCLET>.<PARENTENTITY>.<FIELD>}"

...

:

Codeblock
languagegroovy
stateNumeral = context."#{NUC.Rechnungsposition.rechnung.context}"."#{NUC.Rechnung.nuclosStateNumber}"
  • Logausgaben mit log.info("...") (Fenster → Ausgabe/Scripting).
  • Aktueller Benutzer über die Variable username (ab Nuclos 4.0.15).
  • Groovy-Exceptions werden nicht an den Benutzer weitergegeben – zum Debuggen auffangen und per JOptionPane-Messagebox anzeigen.

Verwandte Seiten

puzzle piece Businessobjekt


Berechnungsausdruck.

Öffnen →

framed picture Layout


Dynamische Feldzustände.

Öffnen →

open book Regeln (serverseitig)


Serverlogik.

Öffnen →

(Warnung) Das Feld, das aus dem Elternbusinessobjek ausgelesen werden soll, muss im Layout vorhanden sein. Soll es nicht sichtbar sein für den Benutzer, kann es deaktiviert werden.

Messagebox anzeigen

Codeblock
languagegroovy
firstline0
linenumberstrue
import groovy.swing.SwingBuilder import javax.swing.* import java.awt.* def swing = new SwingBuilder() def myMainFrame = new Frame() if (context."#{S663.Auftrag.eingangsdatum}" != null) { swing.edt { JOptionPane.showMessageDialog( myMainFrame, "Hello There" ); } }

Debugging

Exceptions die von Groovy-Regeln zur Laufzeit geworfen werfen, werden von Nuclos nicht an den Benutzer weitergegeben. Zu Debuggingzwecken kann man Exceptions auffangen und mit Hilfe der oben beschriebenen Messagebox anzeigen.

Codeblock
languagegroovy
firstline0
linenumberstrue
(...) try { // some code } catch (Exception ex) { swing.edt { JOptionPane.showMessageDialog( myMainFrame, "${ex}" ) } }

Berechnungsrichtung abhängig von einem Parameter ändern

Szenario: Feld A soll aus Feld B berechnet werden, wenn eine boolena-Variable den Wert wahr hat, andernfalls soll Feld B soll aus Feld A berechnet werden.

MessageBox anzeigen

Codeblockimport groovy.swing.SwingBuilder import javax.swing.* import java.awt.* def swing = new SwingBuilder() def myMainFrame = new Frame() if (context."#{S663.Auftrag.eingangsdatum}" != null) { swing.edt { JOptionPane.showMessageDialog( myMainFrame, "Hello There"); } }