From 37d1f78987e7f13788fa2b8d48ba6bc00a56b548 Mon Sep 17 00:00:00 2001
From: "j.goderbauer" <j.goderbauer@adito.de>
Date: Fri, 12 Apr 2019 09:22:41 +0200
Subject: [PATCH] Refactoring Audit: Historylogger

---
 aliasDefinition/Data_alias/Data_alias.aod     |  37 ++-
 .../LogHistory_entity/LogHistory_entity.aod   |  17 +-
 .../recordcontainers/db/orderClauseProcess.js |   7 +
 .../recordcontainers/jdito/contentProcess.js  |  16 +
 .../recordcontainers/jdito/rowCountProcess.js |   0
 .../_____LANGUAGE_en/_____LANGUAGE_en.aod     |   1 +
 .../LogHistoryFilter_view.aod                 |   3 +-
 process/Loghistory_lib/Loghistory_lib.aod     |   1 -
 process/Loghistory_lib/process.js             | 297 ++++++++++--------
 process/process_audit/process.js              |  35 ++-
 process/process_audit/process_audit.aod       |   4 -
 11 files changed, 268 insertions(+), 150 deletions(-)
 create mode 100644 entity/LogHistory_entity/recordcontainers/db/orderClauseProcess.js
 create mode 100644 entity/LogHistory_entity/recordcontainers/jdito/contentProcess.js
 create mode 100644 entity/LogHistory_entity/recordcontainers/jdito/rowCountProcess.js

diff --git a/aliasDefinition/Data_alias/Data_alias.aod b/aliasDefinition/Data_alias/Data_alias.aod
index b0e2585fde..4297b5fe73 100644
--- a/aliasDefinition/Data_alias/Data_alias.aod
+++ b/aliasDefinition/Data_alias/Data_alias.aod
@@ -231,6 +231,13 @@
                 <index v="false" />
                 <title></title>
                 <description></description>
+                <dependencies>
+                  <entityDependency>
+                    <name>c5479d2f-654d-4794-a61e-aee1f2c21673</name>
+                    <entityName>ORGANISATION</entityName>
+                    <fieldName>ORGANISATIONID</fieldName>
+                  </entityDependency>
+                </dependencies>
               </entityFieldDb>
               <entityFieldDb>
                 <name>STATUS</name>
@@ -242,8 +249,20 @@
                 <notNull v="false" />
                 <isUnique v="false" />
                 <index v="false" />
-                <title></title>
+                <title>Status</title>
                 <description></description>
+                <customProperties>
+                  <customStringProperty>
+                    <name>keyword</name>
+                    <global v="false" />
+                    <property>ContactStatus</property>
+                  </customStringProperty>
+                  <customBooleanProperty>
+                    <name>log</name>
+                    <global v="false" />
+                    <property v="true" />
+                  </customBooleanProperty>
+                </customProperties>
               </entityFieldDb>
               <entityFieldDb>
                 <name>PERSON_ID</name>
@@ -447,6 +466,13 @@
                 <index v="false" />
                 <title></title>
                 <description></description>
+                <customProperties>
+                  <customBooleanProperty>
+                    <name>log</name>
+                    <global v="false" />
+                    <property v="true" />
+                  </customBooleanProperty>
+                </customProperties>
               </entityFieldDb>
               <entityFieldDb>
                 <name>MIDDLENAME</name>
@@ -471,8 +497,15 @@
                 <notNull v="false" />
                 <isUnique v="false" />
                 <index v="false" />
-                <title></title>
+                <title>Date of birth</title>
                 <description></description>
+                <customProperties>
+                  <customBooleanProperty>
+                    <name>log</name>
+                    <global v="false" />
+                    <property v="true" />
+                  </customBooleanProperty>
+                </customProperties>
               </entityFieldDb>
               <entityFieldDb>
                 <name>LASTNAME</name>
diff --git a/entity/LogHistory_entity/LogHistory_entity.aod b/entity/LogHistory_entity/LogHistory_entity.aod
index d32a9883c8..dd1433203d 100644
--- a/entity/LogHistory_entity/LogHistory_entity.aod
+++ b/entity/LogHistory_entity/LogHistory_entity.aod
@@ -15,6 +15,7 @@
       <title>Änderungsdatum</title>
       <contentType>DATE</contentType>
       <resolution>SECOND</resolution>
+      <outputFormat></outputFormat>
       <mandatory v="true" />
       <groupable v="true" />
     </entityField>
@@ -40,7 +41,6 @@
     <entityProvider>
       <name>LogHistoryProvider</name>
       <fieldType>DEPENDENCY_IN</fieldType>
-      <recordContainer>db</recordContainer>
       <dependencies>
         <entityDependency>
           <name>23dbfa51-5340-48e3-bd60-e0dcb7d44ad3</name>
@@ -88,6 +88,7 @@
       <title>db</title>
       <alias>Data_alias</alias>
       <conditionProcess>%aditoprj%/entity/LogHistory_entity/recordcontainers/db/conditionProcess.js</conditionProcess>
+      <orderClauseProcess>%aditoprj%/entity/LogHistory_entity/recordcontainers/db/orderClauseProcess.js</orderClauseProcess>
       <linkInformation>
         <linkInformation>
           <name>6becd235-2c53-4ddb-916c-e25da8fc59f5</name>
@@ -116,5 +117,19 @@
         </dbRecordFieldMapping>
       </recordFieldMappings>
     </dbRecordContainer>
+    <jDitoRecordContainer>
+      <name>jdito</name>
+      <jDitoRecordAlias>Data_alias</jDitoRecordAlias>
+      <isPageable v="true" />
+      <isSortable v="true" />
+      <contentProcess>%aditoprj%/entity/LogHistory_entity/recordcontainers/jdito/contentProcess.js</contentProcess>
+      <rowCountProcess>%aditoprj%/entity/LogHistory_entity/recordcontainers/jdito/rowCountProcess.js</rowCountProcess>
+      <recordFields>
+        <element>LOGHISTORYID.value</element>
+        <element>USER_NEW.value</element>
+        <element>DATE_NEW.value</element>
+        <element>DESCRIPTION.value</element>
+      </recordFields>
+    </jDitoRecordContainer>
   </recordContainers>
 </entity>
diff --git a/entity/LogHistory_entity/recordcontainers/db/orderClauseProcess.js b/entity/LogHistory_entity/recordcontainers/db/orderClauseProcess.js
new file mode 100644
index 0000000000..7fcae82e96
--- /dev/null
+++ b/entity/LogHistory_entity/recordcontainers/db/orderClauseProcess.js
@@ -0,0 +1,7 @@
+import("system.db");
+import("system.result");
+
+result.object({
+    "AB_LOGHISTORY.DATE_NEW": db.DESCENDING,
+    "AB_LOGHISTORY.USER_NEW": db.ASCENDING
+});
\ No newline at end of file
diff --git a/entity/LogHistory_entity/recordcontainers/jdito/contentProcess.js b/entity/LogHistory_entity/recordcontainers/jdito/contentProcess.js
new file mode 100644
index 0000000000..7fd238aa4c
--- /dev/null
+++ b/entity/LogHistory_entity/recordcontainers/jdito/contentProcess.js
@@ -0,0 +1,16 @@
+import("Loghistory_lib");
+import("system.vars");
+import("system.db");
+
+//var id = vars.get("$local.idvalue");//TODO: use ID
+
+var dataQuery = "select AB_LOGHISTORY.AB_LOGHISTORYID, AB_LOGHISTORY.USER_NEW, AB_LOGHISTORY.DATE_NEW, AB_LOGHISTORY.DESCRIPTION \n\
+        from AB_LOGHISTORY ";
+
+test()
+test()
+test()
+//TODO: pageable
+//TODO: sortable
+
+var data = db.table(dataQuery);
diff --git a/entity/LogHistory_entity/recordcontainers/jdito/rowCountProcess.js b/entity/LogHistory_entity/recordcontainers/jdito/rowCountProcess.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index 3dae32cda2..7e420651fb 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -697,6 +697,7 @@
     </entry>
     <entry>
       <key>dd.MM.yyyy</key>
+      <value>MM/dd/yyyy</value>
     </entry>
     <entry>
       <key>no valid mail-address format</key>
diff --git a/neonView/LogHistoryFilter_view/LogHistoryFilter_view.aod b/neonView/LogHistoryFilter_view/LogHistoryFilter_view.aod
index a95fd3b08d..045ed5d22d 100644
--- a/neonView/LogHistoryFilter_view/LogHistoryFilter_view.aod
+++ b/neonView/LogHistoryFilter_view/LogHistoryFilter_view.aod
@@ -11,7 +11,8 @@
   <children>
     <tableViewTemplate>
       <name>LogHistoryTable</name>
-      <hideActions v="false" />
+      <hideActions v="true" />
+      <hideContentSearch v="true" />
       <entityField>#ENTITY</entityField>
       <columns>
         <neonTableColumn>
diff --git a/process/Loghistory_lib/Loghistory_lib.aod b/process/Loghistory_lib/Loghistory_lib.aod
index 6ef876b187..454f37cd2f 100644
--- a/process/Loghistory_lib/Loghistory_lib.aod
+++ b/process/Loghistory_lib/Loghistory_lib.aod
@@ -5,6 +5,5 @@
   <process>%aditoprj%/process/Loghistory_lib/process.js</process>
   <variants>
     <element>LIBRARY</element>
-    <element>EXECUTABLE</element>
   </variants>
 </process>
diff --git a/process/Loghistory_lib/process.js b/process/Loghistory_lib/process.js
index f8d96a04fd..41efba3c93 100644
--- a/process/Loghistory_lib/process.js
+++ b/process/Loghistory_lib/process.js
@@ -3,6 +3,7 @@ import("system.logging");
 import("system.project");
 import("system.calendars");
 import("system.db");
+import("system.process");
 import("system.text");
 import("system.datetime");
 import("system.translate");
@@ -14,151 +15,199 @@ import("Contact_lib");
 import("AddressEntity_lib");
 import("Util_lib");
 
-/*
-* Saves changes done to db-coldef that have been turned on for auditing in the repository into the table AB_LOGHISTORY
-*
-* @param {String} pTable req TableName
-* @param {String} pUser req UserName
-* @param {String []} pColumns req ColumnNames
-* @param {String []} pNewValues req new Values
-* @param {String []} pOldValues req old Values
-* @param {Date} pTimeStamp req TimeStamp
-* @param {String} pAction req SQLAction
-* @param {String} pIdValue req IdValue
-* 
-* @return {} void
-*/
+function test()
+{
+    return "asdf";
+}
+
+function LogHistoryExecutor(pTable, pUser, pColumns, pNewValues, pOldValues, pTimeStamp, pAction, pIdValue)
+{
+    this.structureDefinitionAlias = "Data_alias";//alias where the definition of what shall be logged is stored
+    this.oldValues = pOldValues || [];
+    this.newValues = pNewValues || [];
+    this.affectedTable = pTable.toUpperCase();
+    this.triggeringUser = pUser;
+    this.timestamp = pTimeStamp;
+    this.sqlAction = pAction;
+    this.idValue = pIdValue;
+    this.columns = pColumns.map(function (v){
+            return v.toUpperCase();
+        });
+    this.translationLanguage = LogHistoryExecutor.TRANSLATION_LANGUAGE();
+}
 
-function logHistory (pTable, pUser, pColumns, pNewValues, pOldValues, pTimeStamp, pAction, pIdValue)
+LogHistoryExecutor.TRANSLATION_LANGUAGE = function(){
+    return "DE_de";
+}
+
+
+LogHistoryExecutor.prototype._addEntryForInsert = function (pTablename, pTablenameId, pSourceTablename, pSourceTablenameId, pDescription)
+{
+    if (this.toInsert == undefined)
+    {
+        this.toInsert = {
+             statements: []
+            ,cols: ["AB_LOGHISTORYID", "LOGTYPE","TABLENAME","TABLENAMEID","DESCRIPTION", "SOURCE_TABLENAME", "SOURCE_TABLENAMEID", "DATE_NEW","USER_NEW"]
+        };
+        this.toInsert.types = db.getColumnTypes("AB_LOGHISTORY", this.toInsert.cols);//load only once for better performance
+    }
+
+    var vals = [util.getNewUUID(), this.sqlAction, pTablename, pTablenameId, pDescription, pSourceTablename, pSourceTablenameId, this.timestamp, this.triggeringUser];
+    this.toInsert.statements.push(["AB_LOGHISTORY", this.toInsert.cols, this.toInsert.types, vals]);
+};
+
+LogHistoryExecutor.prototype._insertLoghistEntry = function ()
+{
+    if (this.toInsert && this.toInsert.statements)
+        db.inserts(this.toInsert.statements);
+};
+
+LogHistoryExecutor.prototype.execute = function ()
 {
     var references = {};
-    var coldef = {};
+    var columnStructure = {};
     var primaryKey = "";
     var tolog = false;
 
-    pTable = pTable.toUpperCase();
-    pColumns = pColumns.map(function (v){ return v.toUpperCase(); });
 
-    var structure = project.getAliasDefinitionStructure("Data_alias", pTable);
+    var structure = project.getAliasDefinitionStructure(this.structureDefinitionAlias, this.affectedTable);
     if (structure)
     {
-        coldef = structure.tables[pTable].columns;
-        for (var column in coldef)
+        columnStructure = structure.tables[this.affectedTable].columns;
+        for (var column in columnStructure)
         {
-            if (coldef[column].tableRef) references[column] = {table: coldef[column].tableRef, id: ""};
-            if (coldef[column].primaryKey) primaryKey = column;
-            if (coldef[column].log) tolog = coldef[column].log;
+            if (columnStructure[column].tableRef) references[column] = 
+            {
+                table: columnStructure[column].tableRef, 
+                id: ""
+            }
+            if (columnStructure[column].primaryKey)
+                primaryKey = column;
+            if (columnStructure[column].log)
+                tolog = true;
         }
     }
-
     
-    if (tolog)
+    if (!tolog)
+        return null;
+    
+    var idvalue = this.idValue;
+    var description = [];
+    var extra = [];
+    extra["COMMUNICATION"] = {
+        IDs: ["CONTACT_ID", "MEDIUM_ID"],
+        RefTable: "CONTACT",
+        Description: translate.text("Communication", this.translationLanguage)
+    };
+    extra["AB_ATTRIBUTERELATION"] = {
+        IDs: ["OBJECT_ROWID", "AB_ATTRIBUTE_ID"],
+        Description: translate.text("Attribute", this.translationLanguage)
+    };
+
+    if (extra[this.affectedTable])
     {
-        var idvalue = pIdValue;
-        var description = [];
-        var extra = [];
-        extra["COMMUNICATION"] = {
-            IDs: ["CONTACT_ID", "MEDIUM_ID"],
-            RefTable: "CONTACT",
-            Description: "Kommunikation"
-        };
-        extra["AB_ATTRIBUTERELATION"] = {
-            IDs: ["OBJECT_ROWID", "AB_ATTRIBUTE_ID"],
-            Description: "Eigenschaft"
-        };
-        
-        if (extra[pTable])
-        {
-            var conf = extra[pTable];
-            var oldvalues = [];
-            var newvalues = [];
+        var conf = extra[this.affectedTable];
+        var oldvalues = [];
+        var newvalues = [];
 
-            for(i = 0; i < pColumns.length; i++ )
-            {
-                if (pAction == 'D' || pAction == 'U')  oldvalues[pColumns[i]] =  pOldValues[i];
-                if (pAction == 'I' || pAction == 'U')  newvalues[pColumns[i]] =  pNewValues[i];
-            }
-            if (pAction == 'D') newvalues = oldvalues;
-            if ((pAction == 'D' || pAction == 'I') && newvalues[conf.IDs[1]])
+        for(i = 0; i < this.columns.length; i++ )
+        {
+            if (this.sqlAction == 'D' || this.sqlAction == 'U')  oldvalues[this.columns[i]] =  this.oldValues[i];
+            if (this.sqlAction == 'I' || this.sqlAction == 'U')  newvalues[this.columns[i]] =  this.newValues[i];
+        }
+        if (this.sqlAction == 'D') newvalues = oldvalues;
+        if ((this.sqlAction == 'D' || this.sqlAction == 'I') && newvalues[conf.IDs[1]])
+        {
+            idvalue = newvalues[conf.IDs[0]];
+            var data = _getData(this.affectedTable, newvalues[conf.IDs[1]], newvalues);
+            description.push(conf.Description + " " + data[0] + ": '" +  data[1] + "'");
+        }
+        if (this.sqlAction == 'U')
+        {
+            var ids = db.array(db.ROW, "select " + conf.IDs.join(", ") + " from " + this.affectedTable + " where " + this.affectedTable + "ID = '" + pIdValue + "'");
+            idvalue = ids[0];
+            var oldid =  ids[1];
+            if (oldvalues[conf.IDs[1]]) oldid =  oldvalues[conf.IDs[1]];
+            var olddata = _getData(this.affectedTable, oldid, this.oldValues);
+            var newdata = _getData(this.affectedTable, ids[1], newvalues);
+            if (newdata[1] && olddata[1])
             {
-                idvalue = newvalues[conf.IDs[0]];
-                var data = _getData(pTable, newvalues[conf.IDs[1]], newvalues);
-                description.push(conf.Description + " " + data[0] + ": '" +  data[1] + "'");
-            }
-            if (pAction == 'U')
+                if (olddata[0] == newdata[0]) description.push(conf.Description + " " + olddata[0] + " von '" +  olddata[1] + "' auf '" + newdata[1]  + "' ");
+                else description.push(conf.Description + " " + olddata[0] + " von '" +  olddata[1] + "' auf " + conf.Description + " " + newdata[0] + " '" + newdata[1]  + "' ");
+            } 
+            else if(this.affectedTable == "COMMUNICATION")
             {
-                var ids = db.array(db.ROW, "select " + conf.IDs.join(", ") + " from " + pTable + " where " + pTable + "ID = '" + pIdValue + "'");
-                idvalue = ids[0];
-                var oldid =  ids[1];
-                if (oldvalues[conf.IDs[1]]) oldid =  oldvalues[conf.IDs[1]];
-                var olddata = _getData(pTable, oldid, oldvalue);
-                var newdata = _getData(pTable, ids[1], newvalues);
-                if (newdata[1] && olddata[1])
-                {
-                    if (olddata[0] == newdata[0]) description.push(conf.Description + " " + olddata[0] + " von '" +  olddata[1] + "' auf '" + newdata[1]  + "' ");
-                    else description.push(conf.Description + " " + olddata[0] + " von '" +  olddata[1] + "' auf " + conf.Description + " " + newdata[0] + " '" + newdata[1]  + "' ");
-                } 
-                else if(pTable == "COMMUNICATION")
-                {
-                    description.push(conf.Description + " Medium von '" +  olddata[0] + "' auf '" + newdata[0] + "' ");
-                }
+                description.push(conf.Description + " Medium von '" +  olddata[0] + "' auf '" + newdata[0] + "' ");
             }
-            if (conf.RefTable) pTable = conf.RefTable;
-        } //no extra tables
-        else	
+        }
+        if (conf.RefTable) this.affectedTable = conf.RefTable;
+    } //no extra tables
+    else	
+    {
+        if (this.affectedTable == "ASYS_CALENDARBACKEND") 
+        {
+            var entrytypePosition = this.columns.indexOf("ENTRYTYPE");
+            if (entrytypePosition > -1 && this.newValues[entrytypePosition] == calendars.VEVENT)
+                return null;//TODO: wyh return?
+        }
+
+        for (var i = 0; i < this.columns.length; i++)
         {
-            logging.log("no extra table");
-            if (pTable == "ASYS_CALENDARBACKEND") {
-                var entrytypePosition = pColumns.indexOf("ENTRYTYPE");
-                if (entrytypePosition > -1) if (pNewValues[entrytypePosition] == calendars.VEVENT) return;
+            if (this.affectedTable == "ASYS_CALENDARBACKEND" && this.columns[i] == "VCOMPONENT") 
+                _getCalendarDescription(this.sqlAction, i, this.newValues, this.oldValues);
+
+            if (references[this.columns[i]])
+            {
+                if (this.sqlAction == "I") references[this.columns[i]].id = this.newValues[i];
+                if (this.sqlAction == "D") references[this.columns[i]].id = this.oldValues[i];
             }
 
-            for(i = 0; i < pColumns.length; i++ )
+            var logfield = columnStructure[this.columns[i]];
+            if (logfield && logfield.log)
             {
-                if (pTable == "ASYS_CALENDARBACKEND" && pColumns[i] == "VCOMPONENT") _getCalendarDescription(pAction, i, pNewValues, pOldValues);
-                if (references[pColumns[i]])
+                if (this.sqlAction != 'I' && this.oldValues[i] != "") this.oldValues[i] = LogHistoryExecutor._getFormattedValue(logfield, this.oldValues[i], this.translationLanguage);
+                if (this.sqlAction != 'D' && this.newValues[i] != "") this.newValues[i] = LogHistoryExecutor._getFormattedValue(logfield, this.newValues[i], this.translationLanguage);
+                
+                var logfieldTitle = (logfield.title ? translate.text(logfield.title, this.translationLanguage) : translate.text("Value", this.translationLanguage));
+                if (this.sqlAction == 'U' && this.oldValues[i] != this.newValues[i])
                 {
-                    if (pAction == "I") references[pColumns[i]].id = pNewValues[i];
-                    if (pAction == "D") references[pColumns[i]].id = pOldValues[i];
+                    if (this.oldValues[i] == "[CLOB]" || this.oldValues[i] == "")
+                        description.push(translate.withArguments("%0 \"%1\"", [logfieldTitle + ":", this.newValues[i]], this.translationLanguage));
+                    else
+                        description.push(translate.withArguments("%0 from \"%1\" to \"%2\"", [logfieldTitle + ":", this.oldValues[i], this.newValues[i]], this.translationLanguage));
+                        
                 }
-                var logfield = coldef[pColumns[i]];
-                if (logfield && logfield.log)
-                {
-                    if (pAction != 'I' && pOldValues[i] != "") pOldValues[i] = _getFormattedValue(logfield, pOldValues[i]);
-                    if (pAction != 'D' && pNewValues[i] != "") pNewValues[i] = _getFormattedValue(logfield, pNewValues[i]);
-                    if (pAction == 'U' && pOldValues[i] != pNewValues[i])
-                    {
-                        let value = pOldValues[i] == "[CLOB]" || pOldValues[i] == "" ? ":" : ": von '" + pOldValues[i];
-                        description.push(logfield.title + value + "' auf '" + pNewValues[i] + "'");
-                    }
-                    if (pAction == 'I' && pNewValues[i] != "") description.push(logfield.title + ": '" + pNewValues[i] + "'");
-                    if (pAction == 'D' && pOldValues[i] != "") description.push(logfield.title + ": '" + pOldValues[i] + "'");
-                }
-            }
-            if (pAction == "U")
-            {
-                for (var index in references) references[index].id = db.cell("select " + index + " from "  + pTable + " where " + primaryKey + " = '" + pIdValue + "'");
+                if (this.sqlAction == 'I' && this.newValues[i] != "") description.push(logfieldTitle + ": \"" + this.newValues[i] + "\"");
+                if (this.sqlAction == 'D' && this.oldValues[i] != "") description.push(logfieldTitle + ": \"" + this.oldValues[i] + "\"");
             }
         }
-        
-        if (description.length > 0)
+        if (this.sqlAction == "U")
         {
-            if (pAction == 'I') description = description.join(", ") + " eingefügt.";
-            if (pAction == 'U') description = description.join(", ") + " geändert.";
-            if (pAction == 'D') description = description.join(", ") + " gelöscht.";
-            var cols = ["AB_LOGHISTORYID", "LOGTYPE","TABLENAME","TABLENAMEID","DESCRIPTION", "SOURCE_TABLENAME", "SOURCE_TABLENAMEID", "DATE_NEW","USER_NEW"];
-            for (index in references)
+            for (var index in references) references[index].id = db.cell("select " + index + " from "  + this.affectedTable + " where " + primaryKey + " = '" + this.idValue + "'");
+        }
+    }
+
+    if (description.length > 0)
+    {
+        if (this.sqlAction == 'I') description = translate.withArguments("%0 added.", [description.join(", ")], this.translationLanguage);
+        if (this.sqlAction == 'U') description = translate.withArguments("%0 modified.", [description.join(", ")], this.translationLanguage);
+        if (this.sqlAction == 'D') description =  translate.withArguments("%0 deleted.", [description.join(", ")], this.translationLanguage);
+        for (index in references)
+        {
+            if (references[index].id != "")
             {
-                if (references[index].id != "")
-                {
-                    db.insertData("AB_LOGHISTORY", cols, null, [util.getNewUUID(), pAction, references[index].table.trim(), references[index].id, description, pTable.trim(), idvalue, pTimeStamp, pUser]);
-                    idvalue = ""; 
-                }
+                this._addEntryForInsert(references[index].table.trim(), references[index].id, this.affectedTable.trim(), idvalue, description);
+                idvalue = ""; 
             }
-            if (idvalue !=  "") db.insertData("AB_LOGHISTORY", cols, null, [util.getNewUUID(), pAction, pTable.trim(), idvalue, description, "", "", pTimeStamp, pUser]);
+        }
+        if (idvalue !=  "") 
+        {
+            this._addEntryForInsert(this.affectedTable.trim(), idvalue, "", "", description);
         }
     }
-}
+    this._insertLoghistEntry();
+    return null;
+};
 
 /*
 * Creates the data for the tables with special cases
@@ -185,11 +234,10 @@ function _getData(pTable, pId, pValues)
 /*
 * Creates an Array of AB_LOGHISTORY data for display in a view
 *
-* @param {String} pCondition req TableName
 *
 * @return {[]}	table
 */
-function _getFormattedValue(pDescription, pValue)
+LogHistoryExecutor._getFormattedValue = function (pDescription, pValue, pLocale)
 {
     if (pDescription.keyword != null && pDescription.keyword != "")
     {
@@ -198,22 +246,23 @@ function _getFormattedValue(pDescription, pValue)
             pValue = text.decodeMS(pValue);
             for (let i = 0; i < pValue.length; i++)
             {              
-                if (!isNaN(pValue[i])) pValue[i] = getKeyName(pValue[i], pDescription.keyword);
+                if (!isNaN(pValue[i])) pValue[i] = getKeyName(pValue[i], pDescription.keyword);//TODO: keyword
             }
             pValue = pValue.join(", ");
         }
-        else pValue = getKeyName(pValue, pDescription.keyword);
+        else pValue = KeywordUtils.getViewValue(pDescription.keyword, pValue);
     }
     else if (pDescription.translate4Log != null && pDescription.translate4Log != "") 
     {
         var params = {
-             rowId: pIdValue
+             rowId: this.idValue
             ,value: pValue.toString()
-            ,action: pAction
+            ,action: this.sqlAction
         };
-        pValue = evalScript("Loghistory_lib._getFormattedValue", pDescription.translate4Log.replace(/{value}/gi, pValue.toString()), params);
+        
+        pValue = process.executeScript("LogHistoryExecutor._getFormattedValue ", pDescription.translate4Log, params);
     }
-    else if (pDescription.columnType == String(SQLTYPES.TIMESTAMP))  pValue = datetime.toDate(pValue, "dd.MM.yyyy", "Europe/Berlin");
+    else if (pDescription.columnType == String(SQLTYPES.TIMESTAMP))  pValue = datetime.toDate(pValue, translate.text("dd.MM.yyyy", pLocale), "Europe/Berlin");//TODO: timezone?
     else if (pDescription.autoMapTrueFalse4Log) 
     {
         switch (pValue.toLowerCase())
@@ -222,14 +271,14 @@ function _getFormattedValue(pDescription, pValue)
             case "t":
             case "y":
             case "1":
-                pValue = translate.text("Ja");
+                pValue = translate.text("Yes", pLocale);
                 break;
             case "false":
             case "f":
             case "n":
             case "0":
             case "2":
-                pValue = translate.text("Nein");
+                pValue = translate.text("No", pLocale);
                 break;
             default:
                 break;
diff --git a/process/process_audit/process.js b/process/process_audit/process.js
index 12a1329193..3b971f41bb 100644
--- a/process/process_audit/process.js
+++ b/process/process_audit/process.js
@@ -1,17 +1,18 @@
-import("system.logging");
-import("Loghistory_lib");
-import("system.vars");
-
-var tableName = vars.get("$local.table");
-var id = vars.get("$local.idvalue");
-var columns = vars.get("$local.columns");
-var timestamp = vars.get("$local.timestamp");
-var newvalues = vars.get("$local.values");
-var oldvalues = vars.get("$local.oldvalues");
-var sqlAction = vars.get("$local.action");
-var userLogin = vars.get("$local.user");
-
-if (sqlAction != 'X')
-{
-    logHistory(tableName, userLogin, columns, newvalues, oldvalues, timestamp, sqlAction, id);
-}
+import("system.logging");
+import("Loghistory_lib");
+import("system.vars");
+
+var tableName = vars.get("$local.table");
+var id = vars.get("$local.idvalue");
+var columns = vars.get("$local.columns");
+var timestamp = vars.get("$local.timestamp");
+var newvalues = vars.get("$local.values");
+var oldvalues = vars.get("$local.oldvalues");
+var sqlAction = vars.get("$local.action");
+var userLogin = vars.get("$local.user");
+
+if (sqlAction != 'X')
+{
+//    logHistory(tableName, userLogin, columns, newvalues, oldvalues, timestamp, sqlAction, id);
+    (new LogHistoryExecutor(tableName, userLogin, columns, newvalues, oldvalues, timestamp, sqlAction, id)).execute();
+}
diff --git a/process/process_audit/process_audit.aod b/process/process_audit/process_audit.aod
index 2cdbe602ad..55b53099a0 100644
--- a/process/process_audit/process_audit.aod
+++ b/process/process_audit/process_audit.aod
@@ -4,8 +4,4 @@
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <process>%aditoprj%/process/process_audit/process.js</process>
   <alias>Data_alias</alias>
-  <variants>
-    <element>LIBRARY</element>
-    <element>EXECUTABLE</element>
-  </variants>
 </process>
-- 
GitLab