TBayen/Anmerkungen

From ADempiere
Jump to: navigation, search
This Wiki is read-only for reference purposes to avoid broken links.

Amerkungen von Thomas Bayen zu ADempiere

Diese Seite dient erst einmal dazu, alles, was mir auffällt für mich und die Nachwelt festzuhalten. Ich hoffe, diese Informationsstücke später in den Kontext des Wikis einbringen zu können. Wer also Teile hiervon nehmen und verlinken, übersetzen, kopieren oder gar verbessern oder sonstwas möchte, ist gerne hierzu eingeladen. Selbst Meckern ist gewünscht!


technische Grundlagen

ADempiere basiert auf einem JBoss Application Server (in Java) und bietet einen Java Client sowie alternativ einen Webclient mit gleicher Funktionalität. Darüberhinaus gibt es verschiedene Erweiterungen, z.B. für POS oder Produktionsplanung, die zumeist auch Java- oder Webclients bieten.


Demo / deutsche Installation

Eine Live-Demo gibt es unter http://www.testadempiere.com/startdemo.html. Diese ist allerdings nur in Englisch und Spanisch.

Um ein Gefühl für das Programm zu bekommen, wollte ich mir eine Demo ansehen. Leider gibt es auf den Community-Seiten nirgendwo eine eingedeutschte Version. Also habe ich den harten Weg gewählt. Dazu bin ich in folgenden Schritten vorgegangen:


Überblick verschaffen

Zuerst habe ich mir auf http://www.adempiere.com einen Überblick verschafft. Um das Programm zu testen, sind dort drei Möglichkeiten genannt: Eine Online-Demo (siehe oben), ein fertiges Image und eine komplett manuelle Installation. Für den Anfang habe ich mich für den Zweiten Weg entschieden.


AVA-Installation

Das bedeutet, ich habe die AVA-Installation (ADempiere_Virtual_Appliance) gewählt. Hier lädt man ein virtuelles System herunter, das man dann mit VirtualBox ausführen kann. Diese VM liegt im "OVF"-Format vor, so das man sie mit unterschiedlichen Virtualisierungs-Programmen ausführen kann. (sprich: man kann sich VMWare oder VirtualBox aussuchen). Leider benutzt der Erzeuger dieser Dateien wohl VMWare und testet den Start mit VirtualBox nicht. Deshalb gibt es auf o.g. Wikiseite einen Absatz "In case the ovf file does not work". Dank Wiki hat dort jemand reingeschrieben, wie man das Festplattenimage auch ohne die vorgefertigte OVF-Datei zum Laufen bekommt.

Hilfreich ist auch das Dokument "AVA.pdf", das man aus dem Wiki-Artikel heraus laden kann.

Ein weiteres Problem war, das das Festplatten-Image der AVA aus mehreren Dateien besteht und die Verknüpfungen zwischen diesen irgendwie so waren, das man keinen anderen Pfad verwenden darf. Ich weiss nicht, ob man das anpassen kann, habe das Problem aber anders gelöst: Ich habe einfach den Namen der virtuellen Maschine in VirtualBox gleich dem Original gewählt und dann das Festplatten-Image von Hand in das Verzeichnis der Virtualbox-Images kopiert. Dann hat er diese Festplatte schließlich auch akzeptiert.

Nachdem die AVA-Installation lief, habe ich wie im Wiki beschrieben die Netzwerk-Konfiguration des virtuellen Systems angepasst. Leider kam der Adempiere-Server allerdings nicht damit klar, das das Interface jetzt eine andere Adresse hatte. Runterfahren des Servers ging auch nicht, so das ich die ganze virtuelle Maschine nochmal rebootet habe. Danach konnte ich (nach Eintrag des DNS in meine "/etc/hosts", wie in der Anleitung beschrieben) direkt auf http://adempierehost.com:8080 zugreifen und alles war gut.

Die Version des AVA zur Zeit (13.11.2011) ist übrigens die 3.5.3a vom 21.12.2008. Ein Upgrade per ava_agent, wie in der Dokumentation angegeben, ging in Ermangelung ebendieses ava_agent-Binaries nicht.


deutsches Sprachpaket

Die AVA-Installation war zuerst mal nur englisch. Deshalb bin ich der Anleitung auf Sprachpaket_Deutsch gefolgt und habe das deutsche Sprachpaket installiert. Die Datei, die ich dazu aus dem heruntergeladen habe, habe ich über German_Language_Pack gefunden. Das dürfte (soweit ich das verstanden habe) die Übersetzungen der aktuellen Version (z.Zt. 3.7.0) beinhalten. Ich habe sie dennoch installiert und das Ergebnis sah weitgehend gut aus.


aktuelle Installation

Um ehrlich zu sein, hat die Installation einer aktuellen Version aus dem Sourcecode in Eclipse auch nicht viel länger gedauert. Dafür habe ich jetzt eine Version 3.7.0, die sich wirklich an einigen Punkten geändert hat. Im Grunde bin ich dazu den Anweisungen auf Create_your_ADempiere_development_environment gefolgt mit dem Unterschied, das das Projekt inzwischen von Subversion auf Mercurial umgestiegen ist und man den Sourcecode also so erhält, wie auf Mercurial_Test_Environment beschrieben.

Leider muss man immer noch von Hand die deutschen Sprachdateien installieren. Allerdings sind sie im Eclipse-Projekt im Verzeichnis "data" direkt enthalten, so das man wenigsten keine Angst hat ,das die Versionen nicht zusammenpassen...


Installation noch mal ganz von vorne

Obwohl es hier bereits genug Seiten gibt, die sich mit der Installation beschäftigen, möchte ich hier nochmal mienen Weg niederschreiben, um das später mit den anderen vergleichen zu können. Vielleicht kann man dann ja später mal was zusammenlegen...

  • Basissystem: Debian 6.0.3 (squeeze)
  • added "contrib non-free" to /etc/apt/sources.list
  • Weitere Pakete installiert: ssh joe (just my habit) openjdk-6-jdk postgresql
  • adduser adempiere
  • su - adempiere
  • tar xzf xzf Adempiere_370LTS.tar.gz
  • Änderung in /etc/postgresql/8.4/main/postgresql.conf, auf listen="*"
  • Änderung in /etc/postgresql/8.4/main/pg_hba.conf auf host all all 0.0.0.0/0 md5
  • /etc/hosts den eigenen Namen entfernen


Baukasten-Prinzip

Man kann ADempiere auf zwei Weisen betrachten: Zum einen ist es ein fertiges ERP-System, zum anderen ist es ein ERP-Baukasten. Es erlaubt, recht einfach neue Tabellen in der Datenbank anzulegen, dafür dann automatisiert eine CRUD GUI zu erzeugen und so ganz schnell verknüpfte Daten zu verwalten. Dazu werden Tabellen, Spalten, Fenster, Eingabefelder, etc. im sogenannten "Application Dictionary" eingetragen (das geschieht einfach per GUI als System-User). Wer dann hierzu über die reinen Daten noch "Business Logic" einfügen will, kann das dann in Java machen. Natürlich kann man seine eigenen Klassen dann mit dem vorhandenen verknüpfen, indem man die bestehenden Tabellen z.B. um Referenzen auf neue, eigene Objekttypen erweitert.


eigenes Modell

Mit Hilfe des Application Dictionary kann man nun bereits eines Großteil eines Datenmodells abbilden. Dennoch fehlt manchmal die eigene Business-Logik. Um diese zu implementieren, kann man eine eigene Model-Klasse implementieren. Wer einer vorhandenen Klasse Eigenschaften hinzufügen will, kann das mit einer Implementation des ModelValidator Interfaces machen. So kann man alle Events eines Objektes abfangen ohne den Original-Quellcode anrühren zu müssen.

Die eigenen Anpassungen können so am Ende in einem hübschen eigenen JAR-File stehen und überstehen so auch ein Upgrade der ADempiere-Basis.

Um ein echtes eigenes Projekt zu erzeugen, ist es eine gute Idee, einige Hinweise zu beachten. Mir hat Create_your_ADempiere_customization_environment dabei geholfen.


Skript-Programmierung

Die Unterstützung von Skripten scheint relativ neu implementiert zu sein und daher nicht so recht dokumentiert. Im Grunde geht es darum, das man sogenannte "Callouts", das sind externe Funktionen, in einer Skriptsprache direkt in der GUI schreiben kann. Ein Einstieg ist z.B. hier Script_Process. Ich habe auch ein wenig damit herumgespielt. Dabei hat es an einigen Stellen gehakt, die ich hier erklären möchte: Zuerst erstellt man eine "Rule" (Regel). Da steht das Skript drin. Diese Regel kann man jetzt einer Datenbank-Spalte zuordnen. Dort muss man "@script:" gefolgt von dem Namen der Regel eintragen. Dieser beginnt z.B. mit "groovy:". Nun kann man das Groovy-Skript ausführen. Es sollte am Ende die Variable "result" auf einen leeren String setzen. (NULL ergibt auf jeden Fall einen Fehler, was mit einem anderen Rückgabewert geschieht, habe ich noch nicht ausprobiert). Also könnte ein erstes Skript z.B. so aussehen:

{{{

 A_Tab.setValue('description', 'Hello, World!');
 result=""

}}}

Es gibt es diese Callout-Schnittstelle bei der Änderung jedes Feldes. Außerdem kann man Regeln als Befehle über das Menü aufrufen (probiere ich später aus). Natürlich kann man auch ein Skript ausführen, das beim Laden, Speichern, löschen eines Datensatzes o.ä. ausgeführt wird. Hierzu implementiert man einen ~ModelValidator als Skript: Script_ModelValidator


Datenbank-Konventionen

Einige Dinge stehen in keiner Dokumentation nicht drin, weil ja sowieso jeder von Anfang an weiss, das "man das so macht"... Hier ein paar dieser Konventionen und Links dazu:

  • Tabellennamen müssen immer ein Prefix haben. Wenn man eigene Tabellen erzeugt, sollte das Prefix drei Zeichen haben (Prefixe mit ein oder zwei Zeichen werden bei der Benennung eines Modes abgeschnitten und sind dan u.U. nicht mehr eindeutig). Das Prefix sollte immer aus Großbuchstaben bestehen. Siehe Table_Prefix
  • Schlüsselfelder enden immer auf "_ID". Auch Fremdschlüssel!
  • Boolean-Felder sind immer vom Typ "character(1)" und enthalten entweder "Y" oder "N". Ich habe keinen Hinweis finden können, das "boolean"-Felder benutzt werden können und den Versuch schnell abgebrochen, weil es nicht ging. Das ist wohl eine Oracle-Hinterlassenschaft. Man kann sich dran gewöhnen... Wer es"sauberer haben möchte", kann sich ja passende Constraints schreiben oder vielleicht einen [enumerated type] dazu basteln.
  • unter ManPageW_TableandColumn ganz unten unter "Contributions" steht eine Liste der verwendeten Postgres-Datentypen für die unterschiedlichen Feldtypen.


Referenzen/Fremdschlüssel

Eine Referenz von einer Tabelle zu einer anderen (also ein Fremdschlüssel) sollte immer auf "_ID" enden. Die referenzierte Tabelle sollte Identity-Felder (auf deutsch "Schlüssel", nicht "Schlüssel-Spalte", das ist der Primärschlüssel) und Suchfelder haben. Dadurch wird die Tabelle durchsuchbar und man vermeidet seltsame Fehlermeldungen beim Ändern von Datenfeldern.

Eine Referenz auf eine Tabelle LUG_Mitglieder heisst am besten LUG_Mitglieder_ID. Dann funktioniert alles von alleine. Als Referenz-Typ wird automatisch "Table direct" ausgewählt. Ist der Name anders (ist z.B. nötig, wenn man mehrere Felder des gleichen Typs hat), so muss man den Typ "Table" wählen und im Application Directory ein "Referenz"-Objekt dazu anlegen. Dieses ist vom Typ Tabellenreferenz, wo man dann eingibt, wie die Referenz funktionieren soll.

Eine Referenz hat immer den Datentyp "numeric(10)".


Bilder in der Datenbank

Wie fange ich das an...: "Die Geschichte von Bildern in Datenbanken ist eine Geschichte voller Mißverständnisse...". :-) Nun ja - ich persönlich bin ja der Meinung, das es im 21. Jahrhundert, d.h. bei heutigen Festplattengrößen und Datenbank-Systemen kein Problem ist, Bilder in der Datenbank abzulegen. Angesichts der Tatsache, das man dann alle Informationen zu einem Objekt inklusive seiner Bilder an einem Platz zusammen hat, ein gemeinsames Backup hat, eine einzige Technologie zum Zugriff und zur Speicherung benutzt und die Bilder immer synchron zum Rest der Daten sind, ist das meines Erachtens nach sogar die bevorzugte Art, Bilder, die inZusammenhang mit Daten stehen, zu speichern!!! Manche Leute meinen hingegen, man würde damit die arme Datenbank völlig überlasten und das ginge nun mal gar nicht und Binärdaten gehören gefälligst ins Filesystem. Die speichern dann nur einen Filenamen oder eine URL in der Datenbank ab und halten das Ganze irgendwie anders synchron. Wie man dann mit mehreren Usern auf das gleiche Filesystem zugreift, ist hier ein anderes Thema. Nun gut - es gibt für beide Vorgehensweisen Argumente. Leider wurden die von den Adempiere-Entwicklern nicht erhört. :-( Dazu kommt, das der Programmierer der Oberfläche wieder was ganz anderes gemeint hat als der Programmierer der Report Engine...

Eine hübsche Erklärung aller Feldtypen in ADempiere (auch bzgl. Images und Binärdaten) ist übrigens auf Entering_Data_-_Fields_and_Buttons zu finden.

Also los:

Der "ADempiere"-Weg, um Bilder abzuspeichern ist, das diese in die Datenbank kommen (Juhu!). Allerdings muss man dazu eine spezielle Tabelle benutzen. Diese Tabelle ist immer "AD_Image" Das ist einerseits u.U. sinnvoll, weil man diese auf einen eigenen Tablespace legen kann und die Datensätze dann natürlich kleiner und handlicher werden. Andererseits hätte ich auch hier gerne die Wahl gehabt. Auf jeden Fall ist ein Bild in diesem Fall immer eine Referenz auf diese Tabelle. Da wir oben gelernt haben, wie Referenzen aussehen, kann das Datenfeld also in etwa so aussehen:

 Bild_ID numeric(10)

Nun stellt man im Appication Directory im Fenster "Tabellen & Felder" im Feld die Einstellung "Referenz" auf "Image". Das reicht eigentlich schon.

Merkwürdigkeiten

Benutze ich nun allerdings die Funktion "Spalte synchronisieren", die eigentlich die Spaltendefinition in der Datenbank anpassen sollte, wird diese auf den Typ varchar(2000000000) gesetzt. Erstens schreibt ADempiere später beim Editieren dennoch nur eine zehnstellige ID da hinein und zweitens ist der richtige Datentyp für Bilder ja wohl immer noch "bytea"! Vielleicht ist das eine Oracle-Hinterlassenschaft, die noch nicht aufgeräumt ist?!?

Druck

Jetzt sollte man nicht meinen, das man Bilder nun in einem Bericht drucken kann. Das geht nämlich natürlich nicht. Berichte werden im Fenster "Druck-Format" eingerichtet. Dort kann man als Format-Typ "Bild" angeben, was sich erstmal gut anhört. Ich habe es bisher nicht geschafft, ein Bild auszugeben... Es gibt verschiedene Möglichkeiten:

  • Man kann dort eine Bild-URL angeben, was wohl bedeutet, das dort immer das gleiche Bild ausgegeben wird.
  • Man kann "Image Field" ankreuzen. Führt man das aus, beschwert sich das Programm im Log mit einem "File not Found". Es versucht offensichtlich, den Feldinhalt als URL zu betrachten und die Datei aus dem Filesystem zu laden. Hierzu benötigt man wohl kein Image-Feld, sondern ein FileName-Feld. Dieses wird dann aber natürlich nicht inder GUI ausgegeben und ist nur lokal auf einem Filesystem zugänglich.
  • Man kann "Image Attached" ankreuzen. Hatte ich vergessen zu erwähnen, das man in ADempiere jedem Datensatz ein oder mehrere Attachments anfügen kann? - Erstens kann man diese jedoch in der GUI normalerweise nicht mit sehen und nur umständlicher pflegen und zweitens steht da nirgendwo, was passiert, wenn man mehrere Attachments hat. - Ich habe es erstmal nicht probiert.

Hoffnung gibt mir lediglich die Tatsache, das ich vor Jahren das gleiche Problem bereits mit JasperReports durchklamüsert habe und mich erinnere, daß es damit geht. Da man in ADempiere für jeden Report immer auch einen ~JasperReport nehmen kann, sollte es also - wenn auch mit höherem Aufwand - möglich sein, Reporte mit Bildern zu erzeugen. Ich werde das Thema erstmal ruhen lassen und später darauf zurückkommen...


Erzeugen von Views

Wenn man eine bestimmte Ansicht von Daten haben will, z.B. für einen Report, kann man das nicht innerhalb von ADempiere machen. Man erzeugt auf Datenbankebene ein View. Es scheint Konvention zu sein, das dessen Name auf "_V" endet. Dann bindet man dieses ebenso wie eine normale Tabelle ein und erzeugt seinen gewünschten Report. Dabei muss man natürlich darauf achten, das man die Felder alle neu konfigurieren muss. Es gibt bei den "Tabellen" eine Kopierfunktion, die das erleichtern dürfte. Noch wichtig ist, das man den Primärschlüssel, der ja bekanntlich "PPP_Blabla_ID" heisst, nicht in das View aufnehmen muss (kann man doch, dann erzeugt sich das View leichter mit "*", aber man sollte kein Feld dafür in Adempiere erzeugen). Dafür sollte man dann im View eine Spalte "PPP_Blabla_V_ID" stehen, die als Primärschlüssel dient. Beispiel:

{{{

 CREATE VIEW BAY_Artikel_V AS SELECT 

BAY_Artikel.*, BAY_Artikel.BAY_Artikel_ID AS BAY_Artikel_V_ID, AD_Image.binarydata

 FROM BAY_Artikel LEFT OUTER JOIN AD_Image ON BAY_Artikel.Bild_ID=AD_Image.AD_Image_ID

}}}


mehrere Serverinstanzen auf einem Rechner

Prinzipiell kann man zwei Serverinstanzen gleichzeitig starten, z.B. um ein Testsystem in der Nähe zu haben. Da ich das auf meinem Testsystem machen möchte, habe ich mich umgeschaut und dazu erstmal folgendes gefunden:

Anders als in dem erstgenannten Beispiel sollte es eigentlich auch so möglich sein, das man nicht das ganze Verzeichnis kopieren muss. Das bleibt aber späteren Experimenten überlassen...


Read Only Logic

Die Logikfelder, die Adempiere intern prüft, folgen einer recht seltsamen Syntax. Diese ist auf Read_Only_Logic erklärt.


lose Enden

Folgende Dinge sollten noch weitergehend untersucht werden:

-- ThomasBayen