diff --git a/.aditoprj/project.version b/.aditoprj/project.version
index 98f52ffb2f57b665df75334f78ab5f64e3c631ef..e9915da458db417918bf50fedc8e2cae43f09f20 100644
--- a/.aditoprj/project.version
+++ b/.aditoprj/project.version
@@ -1,3 +1,3 @@
 #This file is generated by ADITO designer. Do NOT delete or modify!
-#Wed Jul 17 13:06:20 CEST 2019
+#Wed Jul 17 11:50:23 CEST 2019
 version=5.1.19
diff --git a/.liquibase/Data_alias/basic/2019.1.4/Product_added_ImageBlobs.xml b/.liquibase/Data_alias/basic/2019.1.4/Product_added_ImageBlobs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f9028a849a3a07428876944e6de72175280c4224
--- /dev/null
+++ b/.liquibase/Data_alias/basic/2019.1.4/Product_added_ImageBlobs.xml
@@ -0,0 +1,10 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" 
+    xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+    <changeSet author="j.hoermann" id="27dd5dea-94f2-47e6-88c3-5d5a50d781fa">
+        <addColumn tableName="PRODUCT">
+            <column name="PICTURE" type="LONGBLOB"/>
+        </addColumn>
+    </changeSet>
+</databaseChangeLog>
\ No newline at end of file
diff --git a/.liquibase/Data_alias/basic/2019.1.4/changelog.xml b/.liquibase/Data_alias/basic/2019.1.4/changelog.xml
index 67cf54897e25199432122d0dd4997cad7ed2d8d4..1ddfdf8a087786ece36fbf8a57645f286296e16d 100644
--- a/.liquibase/Data_alias/basic/2019.1.4/changelog.xml
+++ b/.liquibase/Data_alias/basic/2019.1.4/changelog.xml
@@ -177,13 +177,15 @@
 
     <include relativeToChangelogFile="true" file="AditoBasic/create_ab_ctilog.xml"/>
     <include relativeToChangelogFile="true" file="AditoBasic/init_CallDirection.xml"/>
-    <include relativeToChangelogFile="true" file="AditoBasic/init_CallAnswerMode.xml"/>
+    <include relativeToChangelogFile="true" file="AditoBasic/init_CallAnswerMode.xml"/>    
     
     <include relativeToChangelogFile="true" file="alter_appointmentlink.xml"/>
     
     <include relativeToChangelogFile="true" file="AditoBasic/init_NotificationPriority.xml"/>
     <include relativeToChangelogFile="true" file="AditoBasic/init_NotificationState.xml"/>
     
+    <include relativeToChangelogFile="true" file="Product_added_ImageBlobs.xml"/>
+    
     <include relativeToChangelogFile="true" file="Salesorder/create_ordertype_keyword.xml"/>
     <include relativeToChangelogFile="true" file="Salesorder/create_dunninglevel_keyword.xml"/>
     <include relativeToChangelogFile="true" file="Salesorder/update_Salesorder.xml"/>
diff --git a/aliasDefinition/Data_alias/Data_alias.aod b/aliasDefinition/Data_alias/Data_alias.aod
index 904e12a1bb05d14f385145e6015a21812308a64b..024d2d6126d15ff7dc762cd45ef82d1514e27e39 100644
--- a/aliasDefinition/Data_alias/Data_alias.aod
+++ b/aliasDefinition/Data_alias/Data_alias.aod
@@ -1835,6 +1835,20 @@
                 <title>Creation user</title>
                 <description></description>
               </entityFieldDb>
+              <entityFieldDb>
+                <name>PICTURE</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="2004" />
+                <size v="2147483647" />
+                <scale v="0" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <documentation></documentation>
+                <title></title>
+                <description></description>
+              </entityFieldDb>
             </entityFields>
           </entityDb>
           <entityDb>
@@ -10981,284 +10995,6 @@
               </entityFieldDb>
             </entityFields>
           </entityDb>
-          <entityDb>
-            <name>DUPLICATESCANCONDITIONCONFIG</name>
-            <dbName></dbName>
-            <idColumn>ID</idColumn>
-            <idGeneratorType v="0" />
-            <idGeneratorInterval v="1" />
-            <documentation></documentation>
-            <title></title>
-            <description></description>
-            <auditSyncConfig>
-              <name>auditSyncConfig</name>
-              <auditMode v="0" />
-              <syncActive v="false" />
-              <syncComplete v="true" />
-              <syncDirection v="1" />
-              <syncIds></syncIds>
-            </auditSyncConfig>
-            <entityFields>
-              <entityFieldDb>
-                <name>DATE_EDIT</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="91" />
-                <size v="10" />
-                <scale v="0" />
-                <notNull v="false" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>CONDITION</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="2005" />
-                <size v="2147483647" />
-                <scale v="0" />
-                <notNull v="false" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>COUNT_CHARACTERS_TO_USE</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="4" />
-                <size v="10" />
-                <scale v="0" />
-                <notNull v="false" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>DATE_NEW</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="91" />
-                <size v="10" />
-                <scale v="0" />
-                <notNull v="true" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>ID</name>
-                <dbName></dbName>
-                <primaryKey v="true" />
-                <columnType v="1" />
-                <size v="36" />
-                <scale v="0" />
-                <notNull v="true" />
-                <isUnique v="true" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>USER_NEW</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="12" />
-                <size v="50" />
-                <scale v="0" />
-                <notNull v="true" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>DUPLICATESCAN_ID</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="1" />
-                <size v="36" />
-                <scale v="0" />
-                <notNull v="true" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>CONDITION_CONFIG_NAME</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="12" />
-                <size v="200" />
-                <scale v="0" />
-                <notNull v="false" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>USER_EDIT</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="12" />
-                <size v="50" />
-                <scale v="0" />
-                <notNull v="false" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-            </entityFields>
-          </entityDb>
-          <entityDb>
-            <name>DUPLICATESCANNER</name>
-            <dbName></dbName>
-            <idColumn>ID</idColumn>
-            <idGeneratorType v="0" />
-            <idGeneratorInterval v="1" />
-            <documentation></documentation>
-            <title></title>
-            <description></description>
-            <auditSyncConfig>
-              <name>auditSyncConfig</name>
-              <auditMode v="0" />
-              <syncActive v="false" />
-              <syncComplete v="true" />
-              <syncDirection v="1" />
-              <syncIds></syncIds>
-            </auditSyncConfig>
-            <entityFields>
-              <entityFieldDb>
-                <name>DATE_EDIT</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="91" />
-                <size v="10" />
-                <scale v="0" />
-                <notNull v="false" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>FILTER_NAME</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="12" />
-                <size v="200" />
-                <scale v="0" />
-                <notNull v="true" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>DATE_NEW</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="91" />
-                <size v="10" />
-                <scale v="0" />
-                <notNull v="true" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>ID</name>
-                <dbName></dbName>
-                <primaryKey v="true" />
-                <columnType v="1" />
-                <size v="36" />
-                <scale v="0" />
-                <notNull v="true" />
-                <isUnique v="true" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>USER_NEW</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="12" />
-                <size v="50" />
-                <scale v="0" />
-                <notNull v="true" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>ENTITY_TO_SCAN_NAME</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="12" />
-                <size v="200" />
-                <scale v="0" />
-                <notNull v="true" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>EXTERNAL_SERVICE_USAGE_ALLOWED</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="16" />
-                <size v="1" />
-                <scale v="0" />
-                <notNull v="true" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-              <entityFieldDb>
-                <name>USER_EDIT</name>
-                <dbName></dbName>
-                <primaryKey v="false" />
-                <columnType v="12" />
-                <size v="50" />
-                <scale v="0" />
-                <notNull v="false" />
-                <isUnique v="false" />
-                <index v="false" />
-                <documentation></documentation>
-                <title></title>
-                <description></description>
-              </entityFieldDb>
-            </entityFields>
-          </entityDb>
         </entities>
       </entityGroup>
     </aliasDefDb>
diff --git a/entity/360Degree_entity/360Degree_entity.aod b/entity/360Degree_entity/360Degree_entity.aod
index 33f3db7d52bc395bdb010bc9a692190ddacd7d87..acaa21293a751fcc1a7d6942c4ec0ee74ad5ba69 100644
--- a/entity/360Degree_entity/360Degree_entity.aod
+++ b/entity/360Degree_entity/360Degree_entity.aod
@@ -3,6 +3,8 @@
   <name>360Degree_entity</name>
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <title>360 Degree</title>
+  <grantUpdate v="false" />
+  <grantDelete v="false" />
   <recordContainer>jdito</recordContainer>
   <entityFields>
     <entityProvider>
@@ -134,6 +136,11 @@
           <stateProcess>%aditoprj%/entity/360Degree_entity/entityfields/newmodule/children/newcampaignparticipant/stateProcess.js</stateProcess>
           <tooltip>Choose a campaign and a step to add the contact to a  campaign</tooltip>
         </entityActionField>
+        <entityActionField>
+          <name>newSupportticket</name>
+          <onActionProcess>%aditoprj%/entity/360Degree_entity/entityfields/newmodule/children/newsupportticket/onActionProcess.js</onActionProcess>
+          <iconId>VAADIN:QUESTION</iconId>
+        </entityActionField>
       </children>
     </entityActionGroup>
     <entityField>
diff --git a/entity/360Degree_entity/entityfields/newmodule/children/newsupportticket/onActionProcess.js b/entity/360Degree_entity/entityfields/newmodule/children/newsupportticket/onActionProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..9fa788e332e620073941436097faff4ca5269345
--- /dev/null
+++ b/entity/360Degree_entity/entityfields/newmodule/children/newsupportticket/onActionProcess.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("ActivityTask_lib");
+import("Context_lib");
+import("Ticket_lib")
+
+TicketUtils.createNewTicket(undefined, [[vars.get("$param.BaseContextId_param"), vars.get("$param.ObjectRowId_param")]])
\ No newline at end of file
diff --git a/entity/ActivityLink_entity/ActivityLink_entity.aod b/entity/ActivityLink_entity/ActivityLink_entity.aod
index 0f06b6c7e86d6d2939dd3760acb8d0cd5dc613c5..88493b2d733ec4ae70d71fff3be91705f859c57a 100644
--- a/entity/ActivityLink_entity/ActivityLink_entity.aod
+++ b/entity/ActivityLink_entity/ActivityLink_entity.aod
@@ -64,7 +64,6 @@
         <entityParameter>
           <name>ObjectType_param</name>
           <valueProcess>%aditoprj%/entity/ActivityLink_entity/entityfields/objects/children/objecttype_param/valueProcess.js</valueProcess>
-          <expose v="true" />
         </entityParameter>
       </children>
     </entityConsumer>
diff --git a/entity/Activity_entity/recordcontainers/db/onDBInsert.js b/entity/Activity_entity/recordcontainers/db/onDBInsert.js
new file mode 100644
index 0000000000000000000000000000000000000000..3bd6b8b3b9c844e2632f11a231b283d2a46b461a
--- /dev/null
+++ b/entity/Activity_entity/recordcontainers/db/onDBInsert.js
@@ -0,0 +1,10 @@
+import("ActivityTask_lib");
+import("system.vars");
+import("system.db");
+
+var documents = vars.exists("$param.PresetDocuments_param") && vars.getString("$param.PresetDocuments_param");
+if (documents)
+{
+    documents = JSON.parse(documents);
+    ActivityUtils.insertDocuments(vars.get("$field.ACTIVITYID"), documents);
+}
\ No newline at end of file
diff --git a/entity/AddressValidation_entity/AddressValidation_entity.aod b/entity/AddressValidation_entity/AddressValidation_entity.aod
index 6a806e5d68ca8959223108f8d67fd421e79fac97..dbade15ee896dbd553625a114ea9cc733bf913d3 100644
--- a/entity/AddressValidation_entity/AddressValidation_entity.aod
+++ b/entity/AddressValidation_entity/AddressValidation_entity.aod
@@ -48,7 +48,7 @@
     </entityField>
     <entityField>
       <name>ZIP</name>
-      <title>Zip</title>
+      <title>Postcode</title>
     </entityField>
     <entityField>
       <name>CITY</name>
diff --git a/entity/Address_entity/Address_entity.aod b/entity/Address_entity/Address_entity.aod
index 9f280499d59199169c662200537a4611122d9b9b..5af0dc7e06ade1771dcee2f027cb5a481a7cf6c6 100644
--- a/entity/Address_entity/Address_entity.aod
+++ b/entity/Address_entity/Address_entity.aod
@@ -241,12 +241,6 @@
           <fieldName>PossibleAddresses</fieldName>
           <isConsumer v="false" />
         </entityDependency>
-        <entityDependency>
-          <name>716aac15-99cb-4032-bf97-06101f0718f3</name>
-          <entityName>DSGVO_entity</entityName>
-          <fieldName>OrganisationAndContactAdresses</fieldName>
-          <isConsumer v="false" />
-        </entityDependency>
       </dependencies>
       <children>
         <entityParameter>
diff --git a/entity/Address_entity/entityfields/address/mandatoryProcess.js b/entity/Address_entity/entityfields/address/mandatoryProcess.js
index fdba45809693e06d2fa403eb0955864e64ce18c8..80757d2ad1518fcd44a412b1d95dc43aa457617d 100644
--- a/entity/Address_entity/entityfields/address/mandatoryProcess.js
+++ b/entity/Address_entity/entityfields/address/mandatoryProcess.js
@@ -1,5 +1,5 @@
-import("Entity_lib");
-import("system.result");
-import("AddressEntity_lib");
-
-result.object(AddressEntityValidation.isMandatoryField());
\ No newline at end of file
+import("Entity_lib");
+import("system.result");
+import("AddressEntity_lib");
+// TODO: fix validation, then remove comment.
+// result.object(AddressEntityValidation.isMandatoryField());
\ No newline at end of file
diff --git a/entity/Address_entity/entityfields/city/mandatoryProcess.js b/entity/Address_entity/entityfields/city/mandatoryProcess.js
index fdba45809693e06d2fa403eb0955864e64ce18c8..ced83548f6c2f5ed9517d516885fcafc14dc434a 100644
--- a/entity/Address_entity/entityfields/city/mandatoryProcess.js
+++ b/entity/Address_entity/entityfields/city/mandatoryProcess.js
@@ -1,5 +1,6 @@
-import("Entity_lib");
-import("system.result");
-import("AddressEntity_lib");
-
-result.object(AddressEntityValidation.isMandatoryField());
\ No newline at end of file
+import("Entity_lib");
+import("system.result");
+import("AddressEntity_lib");
+
+// TODO: fix validation, then remove comment.
+// result.object(AddressEntityValidation.isMandatoryField());
\ No newline at end of file
diff --git a/entity/Address_entity/entityfields/state/mandatoryProcess.js b/entity/Address_entity/entityfields/state/mandatoryProcess.js
index fdba45809693e06d2fa403eb0955864e64ce18c8..ced83548f6c2f5ed9517d516885fcafc14dc434a 100644
--- a/entity/Address_entity/entityfields/state/mandatoryProcess.js
+++ b/entity/Address_entity/entityfields/state/mandatoryProcess.js
@@ -1,5 +1,6 @@
-import("Entity_lib");
-import("system.result");
-import("AddressEntity_lib");
-
-result.object(AddressEntityValidation.isMandatoryField());
\ No newline at end of file
+import("Entity_lib");
+import("system.result");
+import("AddressEntity_lib");
+
+// TODO: fix validation, then remove comment.
+// result.object(AddressEntityValidation.isMandatoryField());
\ No newline at end of file
diff --git a/entity/Address_entity/entityfields/zip/mandatoryProcess.js b/entity/Address_entity/entityfields/zip/mandatoryProcess.js
index fdba45809693e06d2fa403eb0955864e64ce18c8..ced83548f6c2f5ed9517d516885fcafc14dc434a 100644
--- a/entity/Address_entity/entityfields/zip/mandatoryProcess.js
+++ b/entity/Address_entity/entityfields/zip/mandatoryProcess.js
@@ -1,5 +1,6 @@
-import("Entity_lib");
-import("system.result");
-import("AddressEntity_lib");
-
-result.object(AddressEntityValidation.isMandatoryField());
\ No newline at end of file
+import("Entity_lib");
+import("system.result");
+import("AddressEntity_lib");
+
+// TODO: fix validation, then remove comment.
+// result.object(AddressEntityValidation.isMandatoryField());
\ No newline at end of file
diff --git a/entity/AppointmentLink_entity/AppointmentLink_entity.aod b/entity/AppointmentLink_entity/AppointmentLink_entity.aod
index 7e5d526ca4876e1cab802e065097bd0a352e1525..b9f898507f435bd3fb437adaebf0fb4be3e177ab 100644
--- a/entity/AppointmentLink_entity/AppointmentLink_entity.aod
+++ b/entity/AppointmentLink_entity/AppointmentLink_entity.aod
@@ -79,7 +79,6 @@
         <entityParameter>
           <name>ObjectType_param</name>
           <valueProcess>%aditoprj%/entity/AppointmentLink_entity/entityfields/objects/children/objecttype_param/valueProcess.js</valueProcess>
-          <expose v="true" />
         </entityParameter>
       </children>
     </entityConsumer>
diff --git a/entity/Appointment_entity/Appointment_entity.aod b/entity/Appointment_entity/Appointment_entity.aod
index 3d8bd3b9cf3d3f422d74612aeddb505308724843..1a2a3e9f37ed6503a3e095d34d3a0ce7fb4b9a66 100644
--- a/entity/Appointment_entity/Appointment_entity.aod
+++ b/entity/Appointment_entity/Appointment_entity.aod
@@ -3,9 +3,10 @@
   <name>Appointment_entity</name>
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <documentation>%aditoprj%/entity/Appointment_entity/documentation.adoc</documentation>
-  <title>Termin</title>
+  <title>Appointment</title>
   <siblings />
   <afterUiInit>%aditoprj%/entity/Appointment_entity/afterUiInit.js</afterUiInit>
+  <titlePlural>Appointments</titlePlural>
   <recordContainer>jdito</recordContainer>
   <entityFields>
     <entityField>
diff --git a/entity/Appointment_entity/recordcontainers/jdito/contentProcess.js b/entity/Appointment_entity/recordcontainers/jdito/contentProcess.js
index 240de2d44397c0acee5d8311b5b41941549b68c2..0499835a647ad301bee4e604b05fa99b6fb5eb3f 100644
--- a/entity/Appointment_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/Appointment_entity/recordcontainers/jdito/contentProcess.js
@@ -24,10 +24,10 @@ else if(vars.getString("$param.LinkedAppointmentsFromDashlet_param"))
 {
     var contactid = tools.getCurrentUser()["params"]["contactID"];
     
-    cond.andPrepareValue("AB_APPOINTMENTLINK.OBJECT_ROWID", contactid)
-    var idscond = db.translateCondition(cond.build("1 = 1"));
+    cond.andPrepareIfSet("AB_APPOINTMENTLINK.OBJECT_ROWID", contactid)
+    let idscond = db.translateCondition(cond.build("1 = 1"));
    
-    var appointmentUids = db.table("select APPOINTMENT_ID from AB_APPOINTMENTLINK where " + idscond);
+    let appointmentUids = db.table("select APPOINTMENT_ID from AB_APPOINTMENTLINK where " + idscond);
     result.object(buildEntriesFromUids(appointmentUids));
 }
 
@@ -37,9 +37,9 @@ else if(vars.getString("$param.LinkedAppointmentsFromDashlet_param"))
 else if(vars.getString("$param.LinkedObjectId_param") != undefined)
 {
     cond.andPrepareVars("AB_APPOINTMENTLINK.OBJECT_ROWID", "$param.LinkedObjectId_param")
-    var idscond = db.translateCondition(cond.build("1 = 1"));
+    let idscond = db.translateCondition(cond.build("1 = 1"));
    
-    var appointmentUids = db.table("select APPOINTMENT_ID from AB_APPOINTMENTLINK where " + idscond);
+    let appointmentUids = db.table("select APPOINTMENT_ID from AB_APPOINTMENTLINK where " + idscond);
     result.object(buildEntriesFromUids(appointmentUids));
 }
 /**
diff --git a/entity/Appointment_entity/recordcontainers/jdito/onDelete.js b/entity/Appointment_entity/recordcontainers/jdito/onDelete.js
index 7abca1e85cd72262cbcde93854d041f1a6956211..fe7f38a0fba3c871e577a04aa0d70fee4f8f95e8 100644
--- a/entity/Appointment_entity/recordcontainers/jdito/onDelete.js
+++ b/entity/Appointment_entity/recordcontainers/jdito/onDelete.js
@@ -18,7 +18,7 @@ if (vars.exists("$param.Entry_param"))
      * Deletes ApointmentLinks referring to the deleted Appointment.
      */
     var cond = SqlCondition.begin();
-    cond.andPrepareValue("AB_APPOINTMENTLINK.APPOINTMENT_ID", entry[calendars.ID])
+    cond.andPrepareIfSet("AB_APPOINTMENTLINK.APPOINTMENT_ID", entry[calendars.ID])
     var idscond = db.translateCondition(cond.build("1 = 2"));
     
     db.deleteData("AB_APPOINTMENTLINK", idscond);
diff --git a/entity/AttributeRelation_entity/AttributeRelation_entity.aod b/entity/AttributeRelation_entity/AttributeRelation_entity.aod
index 876d9101af81141c6e4145a28e49aedaf207b363..90f3b32a681e47388a5eb1255ed7ea4c524f2191 100644
--- a/entity/AttributeRelation_entity/AttributeRelation_entity.aod
+++ b/entity/AttributeRelation_entity/AttributeRelation_entity.aod
@@ -2,6 +2,7 @@
 <entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.10" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.10">
   <name>AttributeRelation_entity</name>
   <majorModelMode>DISTRIBUTED</majorModelMode>
+  <title>Attribute</title>
   <grantDeleteProcess>%aditoprj%/entity/AttributeRelation_entity/grantDeleteProcess.js</grantDeleteProcess>
   <titlePlural>Attributes</titlePlural>
   <recordContainer>jdito</recordContainer>
diff --git a/entity/AttributeUsage_entity/recordcontainers/db/onDBDelete.js b/entity/AttributeUsage_entity/recordcontainers/db/onDBDelete.js
index b41e99cd82af7be8fd94faddd41fda7feb3e733e..c3a22ddade799d36cd601b8c6651923aeb730984 100644
--- a/entity/AttributeUsage_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/AttributeUsage_entity/recordcontainers/db/onDBDelete.js
@@ -1,7 +1,7 @@
 import("system.vars");
 import("Attribute_lib");
 
-var attributeId = vars.get("$field.AB_ATTRIBUTE_ID");
-var objectType = vars.get("$field.OBJECT_TYPE");
+var data = vars.get("$local.rowdata");
+var objectType = data["OBJECT_TYPE.value"];
 
 AttributeUsageUtil.deleteChildrenUsages(attributeId, objectType);
\ No newline at end of file
diff --git a/entity/AttributeUsage_entity/recordcontainers/db/onDBInsert.js b/entity/AttributeUsage_entity/recordcontainers/db/onDBInsert.js
index 73c28f291697502a3d36b35e3b5878ecefdf14a1..cb887e053582826c07d856e0371c4cee9c7d91ec 100644
--- a/entity/AttributeUsage_entity/recordcontainers/db/onDBInsert.js
+++ b/entity/AttributeUsage_entity/recordcontainers/db/onDBInsert.js
@@ -1,8 +1,9 @@
 import("system.vars");
 import("Attribute_lib");
 
-var attributeId = vars.get("$field.AB_ATTRIBUTE_ID");
-var objectType = vars.get("$field.OBJECT_TYPE");
+var data = vars.get("$local.rowdata");
+var attributeId = data["AB_ATTRIBUTE_ID.value"];
+var objectType = data["OBJECT_TYPE.value"];
 
 AttributeUsageUtil.insertChildrenUsages(attributeId, objectType);
 AttributeUsageUtil.removeDuplicates(attributeId);
\ No newline at end of file
diff --git a/entity/AttributeUsage_entity/recordcontainers/db/onDBUpdate.js b/entity/AttributeUsage_entity/recordcontainers/db/onDBUpdate.js
index 02890f1b92c8da2fd1f5849ad7855337ba6148ed..c32017dd3c683d7cb23b3da231eda5adeb7423cd 100644
--- a/entity/AttributeUsage_entity/recordcontainers/db/onDBUpdate.js
+++ b/entity/AttributeUsage_entity/recordcontainers/db/onDBUpdate.js
@@ -1,9 +1,10 @@
 import("system.vars");
 import("Attribute_lib");
 
-var attributeId = vars.get("$field.AB_ATTRIBUTE_ID");
+var data = vars.get("$local.rowdata");
+var attributeId = data["AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID"];
 var oldObjectType = vars.get("$context.originalObjectType");
-var newObjectType = vars.get("$field.OBJECT_TYPE");
+var newObjectType = data["AB_ATTRIBUTEUSAGE.OBJECT_TYPE"];
 
 AttributeUsageUtil.updateChildrenUsages(attributeId, oldObjectType, newObjectType);
 AttributeUsageUtil.removeDuplicates(attributeId);
\ No newline at end of file
diff --git a/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js b/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js
index 96d928dedfd2f51c83d050b84b51a34584412990..94b08b434bc0674e06a52691e4bc5d80767f1b50 100644
--- a/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js
+++ b/entity/Attribute_entity/entityfields/attribute_type/stateProcess.js
@@ -21,9 +21,9 @@ if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_EDIT || vars.get("$sys.r
         var hasSubordinate = db.cell(SqlCondition.begin()
             .andPrepareVars("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", "$field.UID")
             .buildSql(
-                "select count(*) = 0 from AB_ATTRIBUTE", "1=2"
+                "select count(*) from AB_ATTRIBUTE", "1=2" //TODO: is there a way exists could be used?
                 )
-            ) != "true";
+            ) != "0";
         if (hasSubordinate)
             state = neon.COMPONENTSTATE_READONLY;
     }
diff --git a/entity/BulkMailAddRecipients_entity/entityfields/recipientcontactids/valueProcess.js b/entity/BulkMailAddRecipients_entity/entityfields/recipientcontactids/valueProcess.js
index 867801eb33a46e2945ad7759d7c48633e8217fc0..107d0af5ed33fdbed773fc5e8bbac0952a303646 100644
--- a/entity/BulkMailAddRecipients_entity/entityfields/recipientcontactids/valueProcess.js
+++ b/entity/BulkMailAddRecipients_entity/entityfields/recipientcontactids/valueProcess.js
@@ -1,21 +1,8 @@
-import("Contact_lib");
-import("system.result");
-import("Bulkmail_lib");
-import("KeywordRegistry_basic");
-import("system.util");
-import("system.db");
-import("Sql_lib");
-import("system.vars");
-
-var contactIds = JSON.parse(vars.getString("$param.ContactIds_param"));
-var bulkMailId = vars.get("$field.BULKMAIL_ID");
-
-var existsQuery = "not exists(select BULKMAILRECIPIENTID from BULKMAILRECIPIENT where BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID and # = ?)";
-var query = SqlCondition.begin()
-    .andIn("CONTACT.CONTACTID", contactIds)
-    .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", bulkMailId, existsQuery) //only add contacts that aren't already recipients
-    .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true))  //check if there's a commrestriction
-    .buildSql("select CONTACTID from CONTACT");
-
-contactIds = db.array(db.COLUMN, query); 
-result.string(JSON.stringify(contactIds));
+import("system.result");
+import("Bulkmail_lib");
+import("system.vars");
+
+var contactIds = JSON.parse(vars.getString("$param.ContactIds_param"));
+var bulkMailId = vars.get("$field.BULKMAIL_ID");
+
+result.string(JSON.stringify(BulkMailUtils.filterNewRecipients(bulkMailId, contactIds)));
\ No newline at end of file
diff --git a/entity/BulkMail_entity/BulkMail_entity.aod b/entity/BulkMail_entity/BulkMail_entity.aod
index 5698ca8c63a18544148231bc0cbc783ff06401cc..eed32e047eeee11830af5758f92e36931aa249c1 100644
--- a/entity/BulkMail_entity/BulkMail_entity.aod
+++ b/entity/BulkMail_entity/BulkMail_entity.aod
@@ -1,210 +1,222 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.10" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.10">
-  <name>BulkMail_entity</name>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <icon>VAADIN:AT</icon>
-  <title>Bulk mail</title>
-  <contentTitleProcess>%aditoprj%/entity/BulkMail_entity/contentTitleProcess.js</contentTitleProcess>
-  <titlePlural>Bulk mails</titlePlural>
-  <recordContainer>db</recordContainer>
-  <entityFields>
-    <entityProvider>
-      <name>#PROVIDER</name>
-      <dependencies>
-        <entityDependency>
-          <name>88f8ded7-fe8f-41ef-8e01-030bae0867ee</name>
-          <entityName>BulkMailAddRecipients_entity</entityName>
-          <fieldName>BulkMails</fieldName>
-          <isConsumer v="false" />
-        </entityDependency>
-      </dependencies>
-    </entityProvider>
-    <entityField>
-      <name>BULKMAILID</name>
-    </entityField>
-    <entityField>
-      <name>NAME</name>
-      <title>Name</title>
-      <mandatory v="true" />
-    </entityField>
-    <entityField>
-      <name>SUBJECT</name>
-      <title>Subject</title>
-    </entityField>
-    <entityField>
-      <name>DESCRIPTION</name>
-      <title>Description</title>
-    </entityField>
-    <entityField>
-      <name>DOCUMENTTEMPLATE_ID</name>
-      <title>Document Template</title>
-      <consumer>Templates</consumer>
-      <mandatory v="false" />
-      <onValueChange>%aditoprj%/entity/BulkMail_entity/entityfields/documenttemplate_id/onValueChange.js</onValueChange>
-    </entityField>
-    <entityConsumer>
-      <name>Recipients</name>
-      <dependency>
-        <name>dependency</name>
-        <entityName>BulkMailRecipient_entity</entityName>
-        <fieldName>BulkMailRecipients</fieldName>
-      </dependency>
-      <children>
-        <entityParameter>
-          <name>BulkMailId_param</name>
-          <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/recipients/children/bulkmailid_param/valueProcess.js</valueProcess>
-        </entityParameter>
-      </children>
-    </entityConsumer>
-    <entityConsumer>
-      <name>Templates</name>
-      <dependency>
-        <name>dependency</name>
-        <entityName>DocumentTemplate_entity</entityName>
-        <fieldName>DocumentTemplateProvider</fieldName>
-      </dependency>
-      <children>
-        <entityParameter>
-          <name>DocumentTemplateType_param</name>
-          <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/templates/children/documenttemplatetype_param/valueProcess.js</valueProcess>
-        </entityParameter>
-        <entityParameter>
-          <name>DocumentTemplateTypeClassification_param</name>
-          <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/templates/children/documenttemplatetypeclassification_param/valueProcess.js</valueProcess>
-        </entityParameter>
-      </children>
-    </entityConsumer>
-    <entityField>
-      <name>STATUS</name>
-      <title>Status</title>
-      <consumer>StatusKeyword</consumer>
-      <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/status/valueProcess.js</valueProcess>
-      <displayValueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/status/displayValueProcess.js</displayValueProcess>
-    </entityField>
-    <entityField>
-      <name>SENDER</name>
-      <title>Sender address</title>
-      <mandatory v="true" />
-      <onValidation>%aditoprj%/entity/BulkMail_entity/entityfields/sender/onValidation.js</onValidation>
-    </entityField>
-    <entityActionField>
-      <name>sendMail</name>
-      <title>Send</title>
-      <onActionProcess>%aditoprj%/entity/BulkMail_entity/entityfields/sendmail/onActionProcess.js</onActionProcess>
-      <iconId>VAADIN:PAPERPLANE</iconId>
-      <stateProcess>%aditoprj%/entity/BulkMail_entity/entityfields/sendmail/stateProcess.js</stateProcess>
-    </entityActionField>
-    <entityField>
-      <name>ICON</name>
-      <contentType>IMAGE</contentType>
-      <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/icon/valueProcess.js</valueProcess>
-    </entityField>
-    <entityField>
-      <name>preview</name>
-      <contentType>HTML</contentType>
-      <displayValueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/preview/displayValueProcess.js</displayValueProcess>
-    </entityField>
-    <entityConsumer>
-      <name>StatusKeyword</name>
-      <dependency>
-        <name>dependency</name>
-        <entityName>KeywordEntry_entity</entityName>
-        <fieldName>SpecificContainerKeywords</fieldName>
-      </dependency>
-      <children>
-        <entityParameter>
-          <name>ContainerName_param</name>
-          <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/statuskeyword/children/containername_param/valueProcess.js</valueProcess>
-        </entityParameter>
-      </children>
-    </entityConsumer>
-    <entityField>
-      <name>BINDATA</name>
-      <contentType>FILE</contentType>
-      <stateProcess>%aditoprj%/entity/BulkMail_entity/entityfields/bindata/stateProcess.js</stateProcess>
-    </entityField>
-    <entityFieldGroup>
-      <name>subjectPreview</name>
-      <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/subjectpreview/valueProcess.js</valueProcess>
-      <fields>
-        <element>SUBJECT</element>
-      </fields>
-    </entityFieldGroup>
-    <entityActionField>
-      <name>openAdminView</name>
-      <title>Open admin view</title>
-      <onActionProcess>%aditoprj%/entity/BulkMail_entity/entityfields/openadminview/onActionProcess.js</onActionProcess>
-      <iconId>VAADIN:CURLY_BRACKETS</iconId>
-      <stateProcess>%aditoprj%/entity/BulkMail_entity/entityfields/openadminview/stateProcess.js</stateProcess>
-    </entityActionField>
-  </entityFields>
-  <recordContainers>
-    <dbRecordContainer>
-      <name>db</name>
-      <alias>Data_alias</alias>
-      <fromClauseProcess>%aditoprj%/entity/BulkMail_entity/recordcontainers/db/fromClauseProcess.js</fromClauseProcess>
-      <onDBInsert>%aditoprj%/entity/BulkMail_entity/recordcontainers/db/onDBInsert.js</onDBInsert>
-      <onDBUpdate>%aditoprj%/entity/BulkMail_entity/recordcontainers/db/onDBUpdate.js</onDBUpdate>
-      <onDBDelete>%aditoprj%/entity/BulkMail_entity/recordcontainers/db/onDBDelete.js</onDBDelete>
-      <linkInformation>
-        <linkInformation>
-          <name>6444866d-42ee-4b7b-8536-6dc8f6437c45</name>
-          <tableName>BULKMAIL</tableName>
-          <primaryKey>BULKMAILID</primaryKey>
-          <isUIDTable v="true" />
-          <readonly v="false" />
-        </linkInformation>
-        <linkInformation>
-          <name>914d6373-4409-44e5-882a-3f795b196d7b</name>
-          <tableName>DOCUMENTTEMPLATE</tableName>
-          <primaryKey>DOCUMENTTEMPLATEID</primaryKey>
-          <isUIDTable v="false" />
-          <readonly v="true" />
-        </linkInformation>
-      </linkInformation>
-      <recordFieldMappings>
-        <dbRecordFieldMapping>
-          <name>BULKMAILID.value</name>
-          <recordfield>BULKMAIL.BULKMAILID</recordfield>
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>DESCRIPTION.value</name>
-          <recordfield>BULKMAIL.DESCRIPTION</recordfield>
-          <isFilterable v="true" />
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>DOCUMENTTEMPLATE_ID.value</name>
-          <recordfield>BULKMAIL.DOCUMENTTEMPLATE_ID</recordfield>
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>NAME.value</name>
-          <recordfield>BULKMAIL.NAME</recordfield>
-          <isFilterable v="true" />
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>SUBJECT.value</name>
-          <recordfield>BULKMAIL.SUBJECT</recordfield>
-          <isFilterable v="true" />
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>SENDER.value</name>
-          <recordfield>BULKMAIL.SENDER</recordfield>
-          <isFilterable v="true" />
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>DOCUMENTTEMPLATE_ID.displayValue</name>
-          <recordfield>DOCUMENTTEMPLATE.NAME</recordfield>
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>STATUS.value</name>
-          <recordfield>BULKMAIL.STATUS</recordfield>
-          <isFilterable v="true" />
-        </dbRecordFieldMapping>
-        <dbRecordFieldMapping>
-          <name>STATUS.displayValue</name>
-          <expression>%aditoprj%/entity/BulkMail_entity/recordcontainers/db/recordfieldmappings/status.displayvalue/expression.js</expression>
-        </dbRecordFieldMapping>
-      </recordFieldMappings>
-    </dbRecordContainer>
-  </recordContainers>
-</entity>
+<?xml version="1.0" encoding="UTF-8"?>
+<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.10" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.10">
+  <name>BulkMail_entity</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <icon>VAADIN:AT</icon>
+  <title>Bulk mail</title>
+  <contentTitleProcess>%aditoprj%/entity/BulkMail_entity/contentTitleProcess.js</contentTitleProcess>
+  <titlePlural>Bulk mails</titlePlural>
+  <recordContainer>db</recordContainer>
+  <entityFields>
+    <entityProvider>
+      <name>#PROVIDER</name>
+      <dependencies>
+        <entityDependency>
+          <name>88f8ded7-fe8f-41ef-8e01-030bae0867ee</name>
+          <entityName>BulkMailAddRecipients_entity</entityName>
+          <fieldName>BulkMails</fieldName>
+          <isConsumer v="false" />
+        </entityDependency>
+      </dependencies>
+    </entityProvider>
+    <entityField>
+      <name>BULKMAILID</name>
+    </entityField>
+    <entityField>
+      <name>NAME</name>
+      <title>Name</title>
+      <mandatory v="true" />
+    </entityField>
+    <entityField>
+      <name>SUBJECT</name>
+      <title>Subject</title>
+    </entityField>
+    <entityField>
+      <name>DESCRIPTION</name>
+      <title>Description</title>
+    </entityField>
+    <entityField>
+      <name>DOCUMENTTEMPLATE_ID</name>
+      <title>Document Template</title>
+      <consumer>Templates</consumer>
+      <mandatory v="false" />
+      <onValueChange>%aditoprj%/entity/BulkMail_entity/entityfields/documenttemplate_id/onValueChange.js</onValueChange>
+    </entityField>
+    <entityConsumer>
+      <name>Recipients</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>BulkMailRecipient_entity</entityName>
+        <fieldName>BulkMailRecipients</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>BulkMailId_param</name>
+          <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/recipients/children/bulkmailid_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
+    <entityConsumer>
+      <name>Templates</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>DocumentTemplate_entity</entityName>
+        <fieldName>DocumentTemplateProvider</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>DocumentTemplateType_param</name>
+          <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/templates/children/documenttemplatetype_param/valueProcess.js</valueProcess>
+        </entityParameter>
+        <entityParameter>
+          <name>DocumentTemplateTypeClassification_param</name>
+          <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/templates/children/documenttemplatetypeclassification_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
+    <entityField>
+      <name>STATUS</name>
+      <title>Status</title>
+      <consumer>StatusKeyword</consumer>
+      <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/status/valueProcess.js</valueProcess>
+      <displayValueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/status/displayValueProcess.js</displayValueProcess>
+    </entityField>
+    <entityField>
+      <name>SENDER</name>
+      <title>Sender address</title>
+      <mandatory v="true" />
+      <onValidation>%aditoprj%/entity/BulkMail_entity/entityfields/sender/onValidation.js</onValidation>
+    </entityField>
+    <entityActionField>
+      <name>sendMail</name>
+      <title>Send</title>
+      <onActionProcess>%aditoprj%/entity/BulkMail_entity/entityfields/sendmail/onActionProcess.js</onActionProcess>
+      <iconId>VAADIN:PAPERPLANE</iconId>
+      <stateProcess>%aditoprj%/entity/BulkMail_entity/entityfields/sendmail/stateProcess.js</stateProcess>
+    </entityActionField>
+    <entityField>
+      <name>ICON</name>
+      <contentType>IMAGE</contentType>
+      <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/icon/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>preview</name>
+      <contentType>HTML</contentType>
+      <displayValueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/preview/displayValueProcess.js</displayValueProcess>
+    </entityField>
+    <entityConsumer>
+      <name>StatusKeyword</name>
+      <dependency>
+        <name>dependency</name>
+        <entityName>KeywordEntry_entity</entityName>
+        <fieldName>SpecificContainerKeywords</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>ContainerName_param</name>
+          <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/statuskeyword/children/containername_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
+    <entityField>
+      <name>BINDATA</name>
+      <contentType>FILE</contentType>
+      <stateProcess>%aditoprj%/entity/BulkMail_entity/entityfields/bindata/stateProcess.js</stateProcess>
+    </entityField>
+    <entityFieldGroup>
+      <name>subjectPreview</name>
+      <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/subjectpreview/valueProcess.js</valueProcess>
+      <fields>
+        <element>SUBJECT</element>
+      </fields>
+    </entityFieldGroup>
+    <entityActionField>
+      <name>openAdminView</name>
+      <title>Open admin view</title>
+      <onActionProcess>%aditoprj%/entity/BulkMail_entity/entityfields/openadminview/onActionProcess.js</onActionProcess>
+      <iconId>VAADIN:CURLY_BRACKETS</iconId>
+      <stateProcess>%aditoprj%/entity/BulkMail_entity/entityfields/openadminview/stateProcess.js</stateProcess>
+    </entityActionField>
+    <entityParameter>
+      <name>PresetRecipients_param</name>
+      <expose v="true" />
+    </entityParameter>
+    <entityField>
+      <name>content</name>
+      <title>Content</title>
+      <contentType>HTML</contentType>
+      <contentTypeProcess>%aditoprj%/entity/BulkMail_entity/entityfields/content/contentTypeProcess.js</contentTypeProcess>
+      <stateProcess>%aditoprj%/entity/BulkMail_entity/entityfields/content/stateProcess.js</stateProcess>
+      <valueProcess>%aditoprj%/entity/BulkMail_entity/entityfields/content/valueProcess.js</valueProcess>
+    </entityField>
+  </entityFields>
+  <recordContainers>
+    <dbRecordContainer>
+      <name>db</name>
+      <alias>Data_alias</alias>
+      <fromClauseProcess>%aditoprj%/entity/BulkMail_entity/recordcontainers/db/fromClauseProcess.js</fromClauseProcess>
+      <onDBInsert>%aditoprj%/entity/BulkMail_entity/recordcontainers/db/onDBInsert.js</onDBInsert>
+      <onDBUpdate>%aditoprj%/entity/BulkMail_entity/recordcontainers/db/onDBUpdate.js</onDBUpdate>
+      <onDBDelete>%aditoprj%/entity/BulkMail_entity/recordcontainers/db/onDBDelete.js</onDBDelete>
+      <linkInformation>
+        <linkInformation>
+          <name>6444866d-42ee-4b7b-8536-6dc8f6437c45</name>
+          <tableName>BULKMAIL</tableName>
+          <primaryKey>BULKMAILID</primaryKey>
+          <isUIDTable v="true" />
+          <readonly v="false" />
+        </linkInformation>
+        <linkInformation>
+          <name>914d6373-4409-44e5-882a-3f795b196d7b</name>
+          <tableName>DOCUMENTTEMPLATE</tableName>
+          <primaryKey>DOCUMENTTEMPLATEID</primaryKey>
+          <isUIDTable v="false" />
+          <readonly v="true" />
+        </linkInformation>
+      </linkInformation>
+      <recordFieldMappings>
+        <dbRecordFieldMapping>
+          <name>BULKMAILID.value</name>
+          <recordfield>BULKMAIL.BULKMAILID</recordfield>
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>DESCRIPTION.value</name>
+          <recordfield>BULKMAIL.DESCRIPTION</recordfield>
+          <isFilterable v="true" />
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>DOCUMENTTEMPLATE_ID.value</name>
+          <recordfield>BULKMAIL.DOCUMENTTEMPLATE_ID</recordfield>
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>NAME.value</name>
+          <recordfield>BULKMAIL.NAME</recordfield>
+          <isFilterable v="true" />
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>SUBJECT.value</name>
+          <recordfield>BULKMAIL.SUBJECT</recordfield>
+          <isFilterable v="true" />
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>SENDER.value</name>
+          <recordfield>BULKMAIL.SENDER</recordfield>
+          <isFilterable v="true" />
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>DOCUMENTTEMPLATE_ID.displayValue</name>
+          <recordfield>DOCUMENTTEMPLATE.NAME</recordfield>
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>STATUS.value</name>
+          <recordfield>BULKMAIL.STATUS</recordfield>
+          <isFilterable v="true" />
+        </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>STATUS.displayValue</name>
+          <expression>%aditoprj%/entity/BulkMail_entity/recordcontainers/db/recordfieldmappings/status.displayvalue/expression.js</expression>
+        </dbRecordFieldMapping>
+      </recordFieldMappings>
+    </dbRecordContainer>
+  </recordContainers>
+</entity>
diff --git a/entity/BulkMail_entity/entityfields/content/contentTypeProcess.js b/entity/BulkMail_entity/entityfields/content/contentTypeProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..e7996a89667933fc400f3fe807ef1a03e8b71f57
--- /dev/null
+++ b/entity/BulkMail_entity/entityfields/content/contentTypeProcess.js
@@ -0,0 +1,15 @@
+import("system.result");
+import("Document_lib");
+import("system.vars");
+
+var upload = vars.get("$field.BINDATA");
+var filename = DocumentUtil.getFilenameFromUpload(upload);
+var type = DocumentUtil.getFileExtensionFromUpload(filename);
+result.string(
+    ({
+        "txt" : "LONG_TEXT",
+        "html" : "HTML",
+        "htm" : "HTML",
+        "eml" : "HTML"
+    })[type] || "LONG_TEXT"
+);
\ No newline at end of file
diff --git a/entity/BulkMail_entity/entityfields/content/stateProcess.js b/entity/BulkMail_entity/entityfields/content/stateProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..3556de9c2f8a50d3a7d0eaee2900e769c1eb2a9c
--- /dev/null
+++ b/entity/BulkMail_entity/entityfields/content/stateProcess.js
@@ -0,0 +1,8 @@
+import("system.result");
+import("system.neon");
+import("system.vars");
+
+if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
+    result.string(neon.COMPONENTSTATE_EDITABLE);
+else
+    result.string(neon.COMPONENTSTATE_INVISIBLE);
\ No newline at end of file
diff --git a/entity/BulkMail_entity/entityfields/content/valueProcess.js b/entity/BulkMail_entity/entityfields/content/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..7b157c6cc8c6ee66d4083c68bee963b411b2748e
--- /dev/null
+++ b/entity/BulkMail_entity/entityfields/content/valueProcess.js
@@ -0,0 +1,24 @@
+import("Document_lib");
+import("system.util");
+import("system.result");
+import("system.vars");
+import("system.db");
+import("DocumentTemplate_lib");
+
+if (vars.get("$this.value") == null)
+{
+    var upload = vars.get("$field.BINDATA");
+    var binData = DocumentUtil.getBindataFromUpload(upload);
+    var filename = DocumentUtil.getFilenameFromUpload(upload);
+    var type = DocumentUtil.getFileExtensionFromUpload(filename);
+    type = ({
+        "txt" : DocumentTemplate.types.TXT,
+        "html" : DocumentTemplate.types.HTML,
+        "htm" : DocumentTemplate.types.HTML,
+        "eml" : DocumentTemplate.types.EML
+    })[type];
+    var template = new DocumentTemplate(binData, type);
+    var content = template.getReplacedContent({}, true);
+
+    result.string(content);
+}
diff --git a/entity/BulkMail_entity/recordcontainers/db/onDBInsert.js b/entity/BulkMail_entity/recordcontainers/db/onDBInsert.js
index 92c78050f4f47399cbc67955957249934a206692..1a0d7b3b5e8ed56dc8088006903a9851f1bbef62 100644
--- a/entity/BulkMail_entity/recordcontainers/db/onDBInsert.js
+++ b/entity/BulkMail_entity/recordcontainers/db/onDBInsert.js
@@ -1,23 +1,35 @@
-import("system.result");
-import("system.vars");
-import("system.db");
-import("system.util");
-import("Document_lib");
-
-//TODO - Function
-
-var bindataUpload = DocumentUtil.getBindataFromUpload(vars.get("$field.BINDATA"));
-var filename = "";
-var bindata = "";
-
-if(bindataUpload != "")
-{
-    filename = DocumentUtil.getFilenameFromUpload(vars.get("$field.BINDATA"));
-    bindata  = bindataUpload;
-}
-
-if(bindata != "" && filename != "")
-{
-    db.insertBinary("BULKMAIL", "DOCUMENT", vars.get("$field.BULKMAILID"), 
-                    "", bindata, filename, "", "", "_____SYSTEMALIAS");
-}
\ No newline at end of file
+import("system.result");
+import("system.vars");
+import("system.db");
+import("system.util");
+import("Document_lib");
+import("Bulkmail_lib");
+
+//TODO - Function
+
+var content = vars.get("$field.content");
+var originalBinData = vars.get("$field.BINDATA");
+var filename;
+
+if(vars.get("$field.BINDATA"))
+    filename = DocumentUtil.getFilenameFromUpload(vars.get("$field.BINDATA"));
+
+var type = DocumentUtil.getFileExtensionFromUpload(filename);
+if (type == "html" || type == "eml")
+    content = "<html>" + content + "</html>";
+
+var bindata = util.encodeBase64String(content);
+if (!filename)
+    filename = vars.get("$field.NAME") + ".txt";
+
+if(bindata != "")
+{
+    db.insertBinary("BULKMAIL", "DOCUMENT", vars.get("$field.BULKMAILID"), 
+                    "", bindata, filename, "", "", "_____SYSTEMALIAS");
+}
+
+var contactIds = JSON.parse(vars.getString("$param.PresetRecipients_param"));
+var bulkMailId = vars.get("$field.BULKMAILID");
+
+if (contactIds && contactIds.length > 0)
+    BulkMailUtils.addRecipients(bulkMailId, BulkMailUtils.filterNewRecipients(bulkMailId, contactIds));
\ No newline at end of file
diff --git a/entity/CampaignAddParticipants_entity/CampaignAddParticipants_entity.aod b/entity/CampaignAddParticipants_entity/CampaignAddParticipants_entity.aod
index d7a2d5cf115655325791b684501b2445df635fc0..3f4826a10805952ed02a39b9dffcdb2f816393bb 100644
--- a/entity/CampaignAddParticipants_entity/CampaignAddParticipants_entity.aod
+++ b/entity/CampaignAddParticipants_entity/CampaignAddParticipants_entity.aod
@@ -37,7 +37,6 @@
     <entityField>
       <name>campaignParticipantMessage</name>
       <state>READONLY</state>
-      <valueProcess>%aditoprj%/entity/CampaignAddParticipants_entity/entityfields/campaignparticipantmessage/valueProcess.js</valueProcess>
       <onValueChangeTypes>
         <element>PROCESS</element>
       </onValueChangeTypes>
diff --git a/entity/CampaignAddParticipants_entity/entityfields/campaignparticipantmessage/valueProcess.js b/entity/CampaignAddParticipants_entity/entityfields/campaignparticipantmessage/valueProcess.js
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/entity/CampaignCost_entity/CampaignCost_entity.aod b/entity/CampaignCost_entity/CampaignCost_entity.aod
index 90d5e5d34feac5bfa738f5b4ba8de88c236b29ed..59886f72bab303c99a88cbb5e5b73fe9d3573b36 100644
--- a/entity/CampaignCost_entity/CampaignCost_entity.aod
+++ b/entity/CampaignCost_entity/CampaignCost_entity.aod
@@ -7,6 +7,7 @@
     <element>CampaignCostChart_entity</element>
   </siblings>
   <afterOperatingState>%aditoprj%/entity/CampaignCost_entity/afterOperatingState.js</afterOperatingState>
+  <titlePlural>Cost entries</titlePlural>
   <recordContainer>db</recordContainer>
   <entityFields>
     <entityProvider>
diff --git a/entity/CampaignParticipant_entity/CampaignParticipant_entity.aod b/entity/CampaignParticipant_entity/CampaignParticipant_entity.aod
index e51b7c68a32f0e1c0675e91be258eb8dc71f9070..eadee452ce6751f048c9998d1fb110e919c04af2 100644
--- a/entity/CampaignParticipant_entity/CampaignParticipant_entity.aod
+++ b/entity/CampaignParticipant_entity/CampaignParticipant_entity.aod
@@ -188,7 +188,6 @@
       <name>ADVERTISINGBAN_ICON</name>
       <colorProcess>%aditoprj%/entity/CampaignParticipant_entity/entityfields/advertisingban_icon/colorProcess.js</colorProcess>
       <contentType>IMAGE</contentType>
-      <stateProcess>%aditoprj%/entity/CampaignParticipant_entity/entityfields/advertisingban_icon/stateProcess.js</stateProcess>
       <valueProcess>%aditoprj%/entity/CampaignParticipant_entity/entityfields/advertisingban_icon/valueProcess.js</valueProcess>
     </entityField>
     <entityConsumer>
diff --git a/entity/CampaignParticipant_entity/entityfields/advertisingban_icon/stateProcess.js b/entity/CampaignParticipant_entity/entityfields/advertisingban_icon/stateProcess.js
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/entity/CampaignStep_entity/CampaignStep_entity.aod b/entity/CampaignStep_entity/CampaignStep_entity.aod
index b206a72faa468d08c591e1de37737a5acca10437..92d59a1b933c236b6a986171d830aa136e2da2bb 100644
--- a/entity/CampaignStep_entity/CampaignStep_entity.aod
+++ b/entity/CampaignStep_entity/CampaignStep_entity.aod
@@ -368,6 +368,12 @@
       <consumer>CampaignStepMedium</consumer>
       <displayValueProcess>%aditoprj%/entity/CampaignStep_entity/entityfields/stepmedium/displayValueProcess.js</displayValueProcess>
     </entityField>
+    <entityActionField>
+      <name>newBulkMail</name>
+      <title>Write bulk mail</title>
+      <onActionProcess>%aditoprj%/entity/CampaignStep_entity/entityfields/newbulkmail/onActionProcess.js</onActionProcess>
+      <iconId>VAADIN:AT</iconId>
+    </entityActionField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
diff --git a/entity/CampaignStep_entity/entityfields/newbulkmail/onActionProcess.js b/entity/CampaignStep_entity/entityfields/newbulkmail/onActionProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..f1ed0b790f38d89d6b30d2eb7de8c8efa3d42a02
--- /dev/null
+++ b/entity/CampaignStep_entity/entityfields/newbulkmail/onActionProcess.js
@@ -0,0 +1,10 @@
+import("Sql_lib");
+import("system.db");
+import("Bulkmail_lib");
+
+var recipients = db.array(db.COLUMN, SqlCondition.begin()
+    .andPrepareVars("CAMPAIGNPARTICIPANT.CAMPAIGNSTEP_ID", "$field.CAMPAIGNSTEPID")
+    .andPrepareVars("CAMPAIGNPARTICIPANT.CAMPAIGN_ID", "$field.CAMPAIGN_ID")
+    .buildSql("select CONTACT_ID from CAMPAIGNPARTICIPANT"));
+
+BulkMailUtils.newBulkMail(recipients);
\ No newline at end of file
diff --git a/entity/Communication_entity/entityfields/addr/onValidation.js b/entity/Communication_entity/entityfields/addr/onValidation.js
index 54a9148c82d2064819c16312df0acd1d96e60870..4724d9c2314f8dff5bc5bfe56efac49e98db0548 100644
--- a/entity/Communication_entity/entityfields/addr/onValidation.js
+++ b/entity/Communication_entity/entityfields/addr/onValidation.js
@@ -11,7 +11,6 @@ import("KeywordRegistry_basic");
 
 var commMedium = vars.get("$field.MEDIUM_ID");
 
-//TODO: maybe accessible via  $property - then it's not needed to load that info twice
 var keywordAttributes = KeywordUtils.getAttributeRelationsByKey(commMedium, $KeywordRegistry.communicationMedium());
 var commCategory = keywordAttributes.contentType || "TEXT";
 
@@ -21,6 +20,7 @@ if (fn != null)
     var commAddr = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.ADDR"));
     var additional = CommValidationUtil.getExtensionsBlueprint();
     additional.countryCode = vars.get("$param.ContactsMainCountry_param");//TODO: try to use users language first and then the companies
+
     var res = fn.call(null, commAddr, additional);
     if (res != null)
         result.string(res);
diff --git a/entity/Communication_entity/entityfields/addr/onValueChange.js b/entity/Communication_entity/entityfields/addr/onValueChange.js
index 82593755b7f91a95c7d063a191d9990782a2ba8e..162a469de3311f5b17c1cff5994e510c1689ca4f 100644
--- a/entity/Communication_entity/entityfields/addr/onValueChange.js
+++ b/entity/Communication_entity/entityfields/addr/onValueChange.js
@@ -1,27 +1,29 @@
-import("WsValidation_lib");
-import("system.neon");
-import("KeywordRegistry_basic");
-import("Keyword_lib");
-import("system.vars");
-
-var addr = vars.get("$local.value");
-
-if (addr)
-{
-    var commMedium = vars.get("$field.MEDIUM_ID");
-    var keywordAttributes = KeywordUtils.getAttributeRelationsByKey(commMedium, $KeywordRegistry.communicationMedium());
-    var commCategory = keywordAttributes.contentType || "TEXT";
-
-    switch (commCategory)
-    {
-        case "TELEPHONE": // Phone
-            if(addr.length > 5)
-            {
-                neon.setFieldValue("$field.ADDR", WsValidationUtils.validate(addr, WsValidationType.get().TYPE_PHONE, vars.get("$param.ContactsMainCountry_param")));
-            }
-            break;
-        default:
-                  
-    }
-    
+import("WsValidation_lib");
+import("system.neon");
+import("KeywordRegistry_basic");
+import("Keyword_lib");
+import("system.vars");
+import("system.cti");
+
+var addr = vars.get("$local.value");
+
+if (addr)
+{
+    var commMedium = vars.get("$field.MEDIUM_ID");
+    var keywordAttributes = KeywordUtils.getAttributeRelationsByKey(commMedium, $KeywordRegistry.communicationMedium());
+    var commCategory = keywordAttributes.contentType || "TEXT";
+
+    switch (commCategory)
+    {
+        case "TELEPHONE": // Phone
+            if(addr.length > 5)
+            {
+                var formatted = cti.formatPhoneNumber(addr, true, vars.get("$param.ContactsMainCountry_param"))
+                neon.setFieldValue("$field.ADDR", cti.formatPhoneNumber(addr, true, vars.get("$param.ContactsMainCountry_param")))
+            }
+            break;
+        default:
+                  
+    }
+    
 }
\ No newline at end of file
diff --git a/entity/Competition_entity/Competition_entity.aod b/entity/Competition_entity/Competition_entity.aod
index 176eb71cb321f736a597c6bcf7444414a95d9e10..53eff28a3c4c5f6ab4682e4417916d7f097f4ee3 100644
--- a/entity/Competition_entity/Competition_entity.aod
+++ b/entity/Competition_entity/Competition_entity.aod
@@ -315,12 +315,10 @@
         <dbRecordFieldMapping>
           <name>DATE_CANCELLED.value</name>
           <recordfield>COMPETITION.DATE_CANCELLED</recordfield>
-          <isFilterable v="true" />
         </dbRecordFieldMapping>
         <dbRecordFieldMapping>
           <name>INFO.value</name>
           <recordfield>COMPETITION.INFO</recordfield>
-          <isFilterable v="true" />
         </dbRecordFieldMapping>
         <dbRecordFieldMapping>
           <name>ORGANISATION_NAME.value</name>
@@ -333,17 +331,14 @@
         <dbRecordFieldMapping>
           <name>REASON.value</name>
           <recordfield>COMPETITION.REASON</recordfield>
-          <isFilterable v="true" />
         </dbRecordFieldMapping>
         <dbRecordFieldMapping>
           <name>CONTACT_ID.value</name>
           <recordfield>COMPETITION.CONTACT_ID</recordfield>
-          <isFilterable v="true" />
         </dbRecordFieldMapping>
         <dbRecordFieldMapping>
           <name>STATUS.value</name>
           <recordfield>COMPETITION.STATUS</recordfield>
-          <isFilterable v="true" />
         </dbRecordFieldMapping>
         <dbRecordFieldMapping>
           <name>CONTACT_ID.displayValue</name>
@@ -372,7 +367,6 @@
         <dbRecordFieldMapping>
           <name>PHASE.value</name>
           <recordfield>COMPETITION.PHASE</recordfield>
-          <isFilterable v="true" />
         </dbRecordFieldMapping>
         <dbRecordFieldMapping>
           <name>OBJECT_ROWID.displayValue</name>
diff --git a/entity/Contract_entity/Contract_entity.aod b/entity/Contract_entity/Contract_entity.aod
index a5103bcad81e5133ff550321475889beb81a7b02..d6fc354289a2a82d710fedc1db831c4901e1b7c2 100644
--- a/entity/Contract_entity/Contract_entity.aod
+++ b/entity/Contract_entity/Contract_entity.aod
@@ -480,6 +480,10 @@
           <name>CONTACT_PERSON_ID.displayValue</name>
           <expression>%aditoprj%/entity/Contract_entity/recordcontainers/db/recordfieldmappings/contact_person_id.displayvalue/expression.js</expression>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>CONTACT_ID.displayValue</name>
+          <expression>%aditoprj%/entity/Contract_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js</expression>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
     </dbRecordContainer>
     <indexRecordContainer>
diff --git a/entity/Contract_entity/entityfields/contact_id/linkedContextProcess.js b/entity/Contract_entity/entityfields/contact_id/linkedContextProcess.js
index 2e504d63e3b5a3f71b54b072798b3ad09c50984b..666b1349748541127d2977a28e6a140ccbf800b1 100644
--- a/entity/Contract_entity/entityfields/contact_id/linkedContextProcess.js
+++ b/entity/Contract_entity/entityfields/contact_id/linkedContextProcess.js
@@ -2,4 +2,4 @@ import("system.vars");
 import("system.result");
 import("Contact_lib");
 
-result.string(ContactUtils.getContextByContactId(vars.getString("$field.CONTACT_ID")));
\ No newline at end of file
+result.string(ContactUtils.getContextByPersOrg(vars.get("$field.CONTACT_PERSON_ID"), vars.get("$field.CONTACT_ORG_ID")));
\ No newline at end of file
diff --git a/entity/Contract_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js b/entity/Contract_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js
new file mode 100644
index 0000000000000000000000000000000000000000..2821fb702f86a860ad359c2ea089f5551743d795
--- /dev/null
+++ b/entity/Contract_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js
@@ -0,0 +1,7 @@
+import("system.vars");
+import("Contact_lib");
+import("system.result");
+
+var contact = Contact.createWithColumnPreset()
+var renderer = new ContactTitleRenderer(contact, ContactTitleRenderer.OPTIONS.IncludeOrganisation);
+result.string(renderer.asSql());
\ No newline at end of file
diff --git a/entity/DSGVO_entity/DSGVO_entity.aod b/entity/DSGVO_entity/DSGVO_entity.aod
index fda4da713fd6781e3e762575a959c6509ed89417..fbaf3f7ff25488adf16b2493b47c3b15fdf7e07a 100644
--- a/entity/DSGVO_entity/DSGVO_entity.aod
+++ b/entity/DSGVO_entity/DSGVO_entity.aod
@@ -12,6 +12,7 @@
   </siblings>
   <grantCreate v="false" />
   <grantDelete v="false" />
+  <titlePlural>Data privacy entries</titlePlural>
   <recordContainer>jdito</recordContainer>
   <entityFields>
     <entityProvider>
@@ -80,20 +81,6 @@
       <name>CONTACT_ID</name>
       <valueProcess>%aditoprj%/entity/DSGVO_entity/entityfields/contact_id/valueProcess.js</valueProcess>
     </entityField>
-    <entityConsumer>
-      <name>OrganisationAndContactAdresses</name>
-      <dependency>
-        <name>dependency</name>
-        <entityName>Address_entity</entityName>
-        <fieldName>OrganisationAndContactAddresses</fieldName>
-      </dependency>
-      <children>
-        <entityParameter>
-          <name>OrganisationId_param</name>
-          <valueProcess>%aditoprj%/entity/DSGVO_entity/entityfields/organisationandcontactadresses/children/organisationid_param/valueProcess.js</valueProcess>
-        </entityParameter>
-      </children>
-    </entityConsumer>
     <entityConsumer>
       <name>KeywordDSGVOPurpose</name>
       <dependency>
@@ -180,7 +167,6 @@
           <isSelectionAction v="true" />
           <iconId>VAADIN:ASTERISK</iconId>
           <state>INVISIBLE</state>
-          <stateProcess>%aditoprj%/entity/DSGVO_entity/entityfields/dsgvoactions/children/anonymperson/stateProcess.js</stateProcess>
         </entityActionField>
       </children>
     </entityActionGroup>
diff --git a/entity/DSGVO_entity/entityfields/dsgvoactions/children/anonymperson/stateProcess.js b/entity/DSGVO_entity/entityfields/dsgvoactions/children/anonymperson/stateProcess.js
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/entity/DSGVO_entity/entityfields/organisationandcontactadresses/children/organisationid_param/valueProcess.js b/entity/DSGVO_entity/entityfields/organisationandcontactadresses/children/organisationid_param/valueProcess.js
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/entity/Forecast_entity/Forecast_entity.aod b/entity/Forecast_entity/Forecast_entity.aod
index a29e767d6adb16103c8c3c04634bcb0f8df97673..b005433286432d702748a9a2c7b25569a376d7ee 100644
--- a/entity/Forecast_entity/Forecast_entity.aod
+++ b/entity/Forecast_entity/Forecast_entity.aod
@@ -3,6 +3,7 @@
   <name>Forecast_entity</name>
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <title>${FORECAST_ENGLISH}</title>
+  <titlePlural>Forecasts</titlePlural>
   <recordContainer>db</recordContainer>
   <entityFields>
     <entityProvider>
diff --git a/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod b/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod
index 9ecc2bf666786892bec59cba0bbad2c78a6153d1..b8c02ae79bc5f5130103f832df4d2dd04e89d205 100644
--- a/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod
+++ b/entity/KeywordAttributeRelation_entity/KeywordAttributeRelation_entity.aod
@@ -4,6 +4,7 @@
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <documentation>%aditoprj%/entity/KeywordAttributeRelation_entity/documentation.adoc</documentation>
   <title>Keyword Attribute Values</title>
+  <titlePlural>Keyword Attribute Values</titlePlural>
   <recordContainer>db</recordContainer>
   <entityFields>
     <entityProvider>
diff --git a/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod b/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod
index 9d8d9c4f9ce387da45eb44d8fe666f681f8984bb..e9d59eaec9a5493a2070cc8a897ef74c011967dd 100644
--- a/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod
+++ b/entity/KeywordAttribute_entity/KeywordAttribute_entity.aod
@@ -53,14 +53,6 @@
           <isConsumer v="false" />
         </entityDependency>
       </dependencies>
-      <children>
-        <entityParameter>
-          <name>ContainerName_param</name>
-        </entityParameter>
-        <entityParameter>
-          <name>FilterAlreadyUsedByEntryId_param</name>
-        </entityParameter>
-      </children>
     </entityProvider>
     <entityParameter>
       <name>ContainerName_param</name>
diff --git a/entity/Letter_entity/recordcontainers/jdito/onInsert.js b/entity/Letter_entity/recordcontainers/jdito/onInsert.js
index 35bc3b14d02877310488934385dc9a5e7472ade0..c2f5bcbd5112cb76c57d5be90df26a6f3d947931 100644
--- a/entity/Letter_entity/recordcontainers/jdito/onInsert.js
+++ b/entity/Letter_entity/recordcontainers/jdito/onInsert.js
@@ -5,10 +5,11 @@ import("DocumentTemplate_lib");
 
 var template = DocumentTemplate.loadTemplate(vars.get("$field.DOCUMENT_TEMPLATE"));
 var contactId = vars.get("$param.ContactId_param");
-neon.download(template.getReplacedContentByContactId(contactId), template.filename);
+var content = template.getReplacedContentByContactId(contactId);
+neon.download(content, template.filename);
 
 var links = [];
 if (contactId)
     links.push(["Person", contactId]); //TODO: dynamic
 
-ActivityUtils.createNewActivity(null, links);
+ActivityUtils.createNewActivity(null, links, null, null, [[template.filename, content, false]]);
diff --git a/entity/Member_entity/Member_entity.aod b/entity/Member_entity/Member_entity.aod
index f4982bb49be0fb2fb4d5fea167a46d48cd70122c..bb144449b860db2ef9b9b472420a9c55af26f8b5 100644
--- a/entity/Member_entity/Member_entity.aod
+++ b/entity/Member_entity/Member_entity.aod
@@ -4,6 +4,7 @@
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <title>${SALESPROJECT_MEMBER}</title>
   <iconId>VAADIN:FILE_SOUND</iconId>
+  <titlePlural>${SALESPROJECT_MEMBER}</titlePlural>
   <recordContainer>db</recordContainer>
   <entityFields>
     <entityProvider>
diff --git a/entity/ObjectRelationType_entity/ObjectRelationType_entity.aod b/entity/ObjectRelationType_entity/ObjectRelationType_entity.aod
index 47481707b3b7611472a18e3581d8e9fba80fd8df..b99283f7f80a053827d38444754406e242d15e30 100644
--- a/entity/ObjectRelationType_entity/ObjectRelationType_entity.aod
+++ b/entity/ObjectRelationType_entity/ObjectRelationType_entity.aod
@@ -7,6 +7,7 @@
   <grantUpdateProcess>%aditoprj%/entity/ObjectRelationType_entity/grantUpdateProcess.js</grantUpdateProcess>
   <grantDeleteProcess>%aditoprj%/entity/ObjectRelationType_entity/grantDeleteProcess.js</grantDeleteProcess>
   <contentTitleProcess>%aditoprj%/entity/ObjectRelationType_entity/contentTitleProcess.js</contentTitleProcess>
+  <titlePlural>Relation types</titlePlural>
   <recordContainer>jdito</recordContainer>
   <entityFields>
     <entityProvider>
diff --git a/entity/Offer_entity/Offer_entity.aod b/entity/Offer_entity/Offer_entity.aod
index ff5478a884d61d663753f354c24510df9866086a..b5fbfbca3ba4fdf99c057e8473deb7e93db28022 100644
--- a/entity/Offer_entity/Offer_entity.aod
+++ b/entity/Offer_entity/Offer_entity.aod
@@ -1090,6 +1090,10 @@
           <name>CONTACT_PERSON_ID.displayValue</name>
           <expression>%aditoprj%/entity/Offer_entity/recordcontainers/db/recordfieldmappings/contact_person_id.displayvalue/expression.js</expression>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>CONTACT_ID.displayValue</name>
+          <expression>%aditoprj%/entity/Offer_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js</expression>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
     </dbRecordContainer>
     <indexRecordContainer>
diff --git a/entity/Offer_entity/entityfields/contact_id/displayValueProcess.js b/entity/Offer_entity/entityfields/contact_id/displayValueProcess.js
index d8f47a34a6c795199277bc1d2930775b4b29e253..85822946ab4fe0ba7730ca93fd6fca69250a5b33 100644
--- a/entity/Offer_entity/entityfields/contact_id/displayValueProcess.js
+++ b/entity/Offer_entity/entityfields/contact_id/displayValueProcess.js
@@ -1,7 +1,6 @@
-import("system.result");
-import("system.vars");
-import("Contact_lib");
-import("system.neon");
-
-
+import("system.result");
+import("system.vars");
+import("Contact_lib");
+import("system.neon");
+
 result.string(ContactUtils.getFullTitleByContactId(vars.getString("$field.CONTACT_ID")));
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/contact_id/linkedContextProcess.js b/entity/Offer_entity/entityfields/contact_id/linkedContextProcess.js
index c6e221c7440633d683f94fcc2505ba548d581b1b..666b1349748541127d2977a28e6a140ccbf800b1 100644
--- a/entity/Offer_entity/entityfields/contact_id/linkedContextProcess.js
+++ b/entity/Offer_entity/entityfields/contact_id/linkedContextProcess.js
@@ -1,5 +1,5 @@
-import("system.vars");
-import("system.result");
-import("Contact_lib");
-
-result.string(ContactUtils.getContextByContactId(vars.getString("$field.CONTACT_ID")));
\ No newline at end of file
+import("system.vars");
+import("system.result");
+import("Contact_lib");
+
+result.string(ContactUtils.getContextByPersOrg(vars.get("$field.CONTACT_PERSON_ID"), vars.get("$field.CONTACT_ORG_ID")));
\ No newline at end of file
diff --git a/entity/Offer_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js b/entity/Offer_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js
new file mode 100644
index 0000000000000000000000000000000000000000..2821fb702f86a860ad359c2ea089f5551743d795
--- /dev/null
+++ b/entity/Offer_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js
@@ -0,0 +1,7 @@
+import("system.vars");
+import("Contact_lib");
+import("system.result");
+
+var contact = Contact.createWithColumnPreset()
+var renderer = new ContactTitleRenderer(contact, ContactTitleRenderer.OPTIONS.IncludeOrganisation);
+result.string(renderer.asSql());
\ No newline at end of file
diff --git a/entity/Product_entity/Product_entity.aod b/entity/Product_entity/Product_entity.aod
index a40f3fa42cd2c6e1f4e4db6d7634ecc4f71903fe..23567b7dfb7df267dc8d5d0604a86a981e53cf62 100644
--- a/entity/Product_entity/Product_entity.aod
+++ b/entity/Product_entity/Product_entity.aod
@@ -10,7 +10,6 @@
   <contentTitleProcess>%aditoprj%/entity/Product_entity/contentTitleProcess.js</contentTitleProcess>
   <afterUiInit>%aditoprj%/entity/Product_entity/afterUiInit.js</afterUiInit>
   <iconId>VAADIN:HAMMER</iconId>
-  <imageProcess>%aditoprj%/entity/Product_entity/imageProcess.js</imageProcess>
   <titlePlural>Products</titlePlural>
   <recordContainer>db</recordContainer>
   <entityFields>
@@ -128,13 +127,9 @@
       </children>
     </entityConsumer>
     <entityField>
-      <name>IMAGE</name>
+      <name>PICTURE</name>
       <contentType>IMAGE</contentType>
-      <valueProcess>%aditoprj%/entity/Product_entity/entityfields/image/valueProcess.js</valueProcess>
-      <onValueChange>%aditoprj%/entity/Product_entity/entityfields/image/onValueChange.js</onValueChange>
-      <onValueChangeTypes>
-        <element>MASK</element>
-      </onValueChangeTypes>
+      <displayValueProcess>%aditoprj%/entity/Product_entity/entityfields/picture/displayValueProcess.js</displayValueProcess>
     </entityField>
     <entityConsumer>
       <name>StockCounts</name>
@@ -556,6 +551,10 @@
           <name>CONTACT_ID.displayValue</name>
           <recordfield>ORGANISATION.NAME</recordfield>
         </dbRecordFieldMapping>
+        <dbRecordFieldMapping>
+          <name>PICTURE.value</name>
+          <recordfield>PRODUCT.PICTURE</recordfield>
+        </dbRecordFieldMapping>
       </recordFieldMappings>
     </dbRecordContainer>
     <indexRecordContainer>
diff --git a/entity/Product_entity/entityfields/image/onValueChange.js b/entity/Product_entity/entityfields/image/onValueChange.js
deleted file mode 100644
index 1fc5daeeea2101848906d4ec2c0f78ebc23fd634..0000000000000000000000000000000000000000
--- a/entity/Product_entity/entityfields/image/onValueChange.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import("system.vars");
-import("Entity_lib");
-
-// TODO: also there is currently no good way to do updates with fields not connected to the record container. Workaround: imagevariable and update in onDBUpdate Process #1030023
-FieldChanges.setChange("$field.IMAGE");
\ No newline at end of file
diff --git a/entity/Product_entity/entityfields/image/valueProcess.js b/entity/Product_entity/entityfields/image/valueProcess.js
deleted file mode 100644
index a02ae76ca2bfe7aefcadf452c09cbbdcc11413ad..0000000000000000000000000000000000000000
--- a/entity/Product_entity/entityfields/image/valueProcess.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import("system.result");
-import("system.neon");
-import("system.vars");
-import("Product_lib");
-
-result.string(ProductUtils.getImage(vars.get("$field.PRODUCTID"), vars.getString("$field.PRODUCTNAME")));
\ No newline at end of file
diff --git a/entity/Product_entity/entityfields/picture/displayValueProcess.js b/entity/Product_entity/entityfields/picture/displayValueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..61071fa5de14d9b69e322e75eed3c546b8ab9e8b
--- /dev/null
+++ b/entity/Product_entity/entityfields/picture/displayValueProcess.js
@@ -0,0 +1,10 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_VIEW) {
+    if (vars.get("$this.value"))
+        result.string(vars.get("$this.value"));
+    else
+        result.string(vars.get("$param.ProductText_param"));
+}
diff --git a/entity/Product_entity/imageProcess.js b/entity/Product_entity/imageProcess.js
deleted file mode 100644
index 73e048a22cc0459fe33d9df5747bcac6a56acbb9..0000000000000000000000000000000000000000
--- a/entity/Product_entity/imageProcess.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import("system.vars");
-import("system.result");
-
-result.string(vars.get("$param.ProductText_param"));
\ No newline at end of file
diff --git a/entity/Productprice_entity/Productprice_entity.aod b/entity/Productprice_entity/Productprice_entity.aod
index 5b222a4fa79654c633c2e7f92ccef30370438eeb..7830dbbf61a1d6316c3a4c744319ecf9e1f464e8 100644
--- a/entity/Productprice_entity/Productprice_entity.aod
+++ b/entity/Productprice_entity/Productprice_entity.aod
@@ -9,6 +9,7 @@
   </siblings>
   <onValidation>%aditoprj%/entity/Productprice_entity/onValidation.js</onValidation>
   <afterOperatingState>%aditoprj%/entity/Productprice_entity/afterOperatingState.js</afterOperatingState>
+  <titlePlural>Prices</titlePlural>
   <recordContainer>db</recordContainer>
   <entityFields>
     <entityField>
diff --git a/entity/Productprice_entity/entityfields/currency/valueProcess.js b/entity/Productprice_entity/entityfields/currency/valueProcess.js
index 081cebb3e478a2c2c0b001db3ac3baab9dba0caa..f07b41ba6feeb577ba324ece8c0be4a29387d888 100644
--- a/entity/Productprice_entity/entityfields/currency/valueProcess.js
+++ b/entity/Productprice_entity/entityfields/currency/valueProcess.js
@@ -1,8 +1,9 @@
 import("system.result");
 import("system.neon");
 import("system.vars");
+import("KeywordRegistry_basic");
 
 if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
 {
-    result.string("EUR");
+    result.string($KeywordRegistry.currency$eur());
 }
\ No newline at end of file
diff --git a/entity/Productprice_entity/entityfields/pricelist/displayValueProcess.js b/entity/Productprice_entity/entityfields/pricelist/displayValueProcess.js
index 08f788cf3daf8433d28d1780a17df2152be6d3d2..96cfba0a256a31f864715f71bc0016b2248878df 100644
--- a/entity/Productprice_entity/entityfields/pricelist/displayValueProcess.js
+++ b/entity/Productprice_entity/entityfields/pricelist/displayValueProcess.js
@@ -7,7 +7,7 @@ import("Sql_lib");
 import("system.text");
 import("KeywordRegistry_basic");
 
-var pricelistname = vars.get("$field.PRICELIST").trim();
+var pricelistname = vars.get("$field.PRICELIST");
 if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_VIEW && !pricelistname)
 {
     var preparedStatement = SqlCondition.begin().andPrepare("CONTACT.CONTACTID", vars.get("$field.CONTACT_ID"));
diff --git a/entity/Productprice_entity/entityfields/pricelist/valueProcess.js b/entity/Productprice_entity/entityfields/pricelist/valueProcess.js
index f9c9524cedcd93dab192369848c72be7cfdd2329..02f050e0d94e76f13b349e68c5582aa8be78e031 100644
--- a/entity/Productprice_entity/entityfields/pricelist/valueProcess.js
+++ b/entity/Productprice_entity/entityfields/pricelist/valueProcess.js
@@ -1,8 +1,9 @@
 import("system.result");
 import("system.neon");
 import("system.vars");
+import("KeywordRegistry_basic");
 
 if (vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
 {
-    result.string("02553fc7-4611-4914-8ff5-0b7c4e7531c9");
+    result.string($KeywordRegistry.productPricelist$standardList());
 }
\ No newline at end of file
diff --git a/entity/Role_entity/Role_entity.aod b/entity/Role_entity/Role_entity.aod
index e5cb9b35a388fca781b734d6a5fc8ff6672403d2..be73dbe9c2d4ac111ed5ee91cb7888d23df6bbb0 100644
--- a/entity/Role_entity/Role_entity.aod
+++ b/entity/Role_entity/Role_entity.aod
@@ -6,6 +6,7 @@
   <title>Roles</title>
   <contentTitleProcess>%aditoprj%/entity/Role_entity/contentTitleProcess.js</contentTitleProcess>
   <iconId>VAADIN:USER_CHECK</iconId>
+  <titlePlural>Roles</titlePlural>
   <recordContainer>jDito</recordContainer>
   <entityFields>
     <entityProvider>
diff --git a/entity/SupportTicket_entity/SupportTicket_entity.aod b/entity/SupportTicket_entity/SupportTicket_entity.aod
index 2401807411b8b2af781995f3512361b8c7de0f33..b5e3e6dd8591c73f6d4e30c6bc5ced712ccebb1c 100644
--- a/entity/SupportTicket_entity/SupportTicket_entity.aod
+++ b/entity/SupportTicket_entity/SupportTicket_entity.aod
@@ -2,8 +2,12 @@
 <entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.10" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.10">
   <name>SupportTicket_entity</name>
   <majorModelMode>DISTRIBUTED</majorModelMode>
-  <title>Supportticket</title>
+  <title>Support Ticket</title>
+  <contentTitleProcess>%aditoprj%/entity/SupportTicket_entity/contentTitleProcess.js</contentTitleProcess>
+  <afterUiInit>%aditoprj%/entity/SupportTicket_entity/afterUiInit.js</afterUiInit>
+  <onValidation>%aditoprj%/entity/SupportTicket_entity/onValidation.js</onValidation>
   <iconId>VAADIN:CHAT</iconId>
+  <titlePlural>Support Tickets</titlePlural>
   <recordContainer>db</recordContainer>
   <entityFields>
     <entityProvider>
@@ -361,6 +365,10 @@
       <onActionProcess>%aditoprj%/entity/SupportTicket_entity/entityfields/newsupportticket/onActionProcess.js</onActionProcess>
       <iconId>VAADIN:QUESTION</iconId>
     </entityActionField>
+    <entityParameter>
+      <name>PresetLinks_param</name>
+      <expose v="true" />
+    </entityParameter>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
diff --git a/entity/SupportTicket_entity/afterUiInit.js b/entity/SupportTicket_entity/afterUiInit.js
new file mode 100644
index 0000000000000000000000000000000000000000..bf767e8d66bdf98162be04e45d523c10384d49e9
--- /dev/null
+++ b/entity/SupportTicket_entity/afterUiInit.js
@@ -0,0 +1,8 @@
+import("system.neon");
+import("system.vars");
+import("ActivityTask_lib");
+
+if(vars.get("$sys.recordstate") == neon.OPERATINGSTATE_NEW)
+{
+    TaskUtils.addLinkRecords("$param.ObjectId_param", "$param.RowId_param", "$param.PresetLinks_param", "$field.PARENT_CONTEXT", "$field.PARENT_ID");
+}
\ No newline at end of file
diff --git a/entity/SupportTicket_entity/contentTitleProcess.js b/entity/SupportTicket_entity/contentTitleProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..42200983cd942d93065d3728601f40eb2cc2d4ad
--- /dev/null
+++ b/entity/SupportTicket_entity/contentTitleProcess.js
@@ -0,0 +1,4 @@
+import("system.vars");
+import("system.result");
+
+result.string(vars.get("$field.TYPE.displayValue"))
\ No newline at end of file
diff --git a/entity/SupportTicket_entity/onValidation.js b/entity/SupportTicket_entity/onValidation.js
new file mode 100644
index 0000000000000000000000000000000000000000..d6ce533ea718a7917f32b17cb1152b2b2e240413
--- /dev/null
+++ b/entity/SupportTicket_entity/onValidation.js
@@ -0,0 +1,9 @@
+import("system.result");
+import("Date_lib");
+import("system.vars");
+
+var startDate = vars.get("$field.TASK_START_DATE");
+var endDate = vars.get("$field.TASK_MATURITY_DATE");
+
+if (!DateUtils.validateBeginnBeforeEnd(startDate, endDate))
+    result.string(DateUtils.getValidationFailString());
\ No newline at end of file
diff --git a/entity/Timetracking_entity/Timetracking_entity.aod b/entity/Timetracking_entity/Timetracking_entity.aod
index 783e707b192651c1898e19a4cb96681b9f22547b..f63061dc36d61dccfac43993ffddb5ab248112d4 100644
--- a/entity/Timetracking_entity/Timetracking_entity.aod
+++ b/entity/Timetracking_entity/Timetracking_entity.aod
@@ -3,6 +3,7 @@
   <name>Timetracking_entity</name>
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <title>Timetracking</title>
+  <titlePlural>Timetracking entries</titlePlural>
   <recordContainer>db</recordContainer>
   <entityFields>
     <entityProvider>
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index f5f38ebd278688ce358e72f875f29767ff1ca1f4..5e58b29c1c4e713fbfcda5b145baf6e72c63ea64 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -5013,6 +5013,54 @@
     <entry>
       <key>New Notifications</key>
     </entry>
+    <entry>
+      <key>Forecasts</key>
+    </entry>
+    <entry>
+      <key>Relation types</key>
+    </entry>
+    <entry>
+      <key>Data privacy entries</key>
+    </entry>
+    <entry>
+      <key>Timetracking entries</key>
+    </entry>
+    <entry>
+      <key>Duplicatescans</key>
+    </entry>
+    <entry>
+      <key>Appointments</key>
+    </entry>
+    <entry>
+      <key>Support Tickets</key>
+    </entry>
+    <entry>
+      <key>Members</key>
+    </entry>
+    <entry>
+      <key>Cost entries</key>
+    </entry>
+    <entry>
+      <key>no valid phone number</key>
+    </entry>
+    <entry>
+      <key>Prognose</key>
+    </entry>
+    <entry>
+      <key>EntityToFilterParam</key>
+    </entry>
+    <entry>
+      <key>Sender</key>
+    </entry>
+    <entry>
+      <key>parameter</key>
+    </entry>
+    <entry>
+      <key>Test DuplicateSearch</key>
+    </entry>
+    <entry>
+      <key>Write bulk mail</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
   <sqlModels>
diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
index c4ec9abe342a192ab487ff8a91dcc24f6e1b02b9..11ccd000ad0997ff5e1fbdacb9e983c3ba551de7 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -34,10 +34,17 @@
       <key>Anonymization</key>
       <value>Anonymisierung</value>
     </entry>
+    <entry>
+      <key>Members</key>
+    </entry>
     <entry>
       <key>The following data has been anonymised: %0</key>
       <value>Die folgenden Daten wurden anonymisiert: %0</value>
     </entry>
+    <entry>
+      <key>Write bulk mail</key>
+      <value>Serienmail schreiben</value>
+    </entry>
     <entry>
       <key>MAX</key>
       <value>maximal</value>
@@ -145,6 +152,9 @@
       <key>Disclosure Report</key>
       <value>Auskunftsbericht</value>
     </entry>
+    <entry>
+      <key>Forecasts</key>
+    </entry>
     <entry>
       <key>Abscences</key>
       <value>Abszenzenen</value>
@@ -560,6 +570,9 @@
       <key>${COUNT_PREPOSITION_MULTIPLE}</key>
       <value>mal</value>
     </entry>
+    <entry>
+      <key>Data privacy entries</key>
+    </entry>
     <entry>
       <key>Email must be unique!</key>
       <value>Die E-Mail-Adresse muss eindeutig sein!</value>
@@ -668,6 +681,9 @@
       <key>The person is already associated with another employee!</key>
       <value>Die Person ist bereits mit einem anderen Mitarbeiter verknüpft!</value>
     </entry>
+    <entry>
+      <key>Appointments</key>
+    </entry>
     <entry>
       <key>Time expenses</key>
       <value>Aufwand</value>
@@ -1510,6 +1526,9 @@
       <key>Remark</key>
       <value>Anmerkung</value>
     </entry>
+    <entry>
+      <key>Cost entries</key>
+    </entry>
     <entry>
       <key>Competition</key>
       <value>Mitbewerber</value>
@@ -1690,6 +1709,7 @@
     </entry>
     <entry>
       <key>no valid format</key>
+      <value>kein gültiges Format</value>
     </entry>
     <entry>
       <key>Deliveryspecification</key>
@@ -1788,6 +1808,7 @@
     </entry>
     <entry>
       <key>no valid mail-address format</key>
+      <value>keine gültige E-Mail Adresse</value>
     </entry>
     <entry>
       <key>Amount</key>
@@ -2030,6 +2051,9 @@
       <key>{$TASK_PRIORITY_LOW}</key>
       <value>niedrig</value>
     </entry>
+    <entry>
+      <key>Duplicatescans</key>
+    </entry>
     <entry>
       <key>Nur Eigene anzeigen</key>
     </entry>
@@ -2249,6 +2273,9 @@
       <key>Product_functionality</key>
       <value>Produkt_Funktionalität</value>
     </entry>
+    <entry>
+      <key>Timetracking entries</key>
+    </entry>
     <entry>
       <key>New appointment</key>
       <value>Neuer Termin</value>
@@ -4997,6 +5024,7 @@
     </entry>
     <entry>
       <key>Salutations</key>
+      <value>Anreden</value>
     </entry>
     <entry>
       <key>Paymentterm</key>
@@ -5104,9 +5132,6 @@
     <entry>
       <key>Bug Ticket</key>
     </entry>
-    <entry>
-      <key>Support ticket</key>
-    </entry>
     <entry>
       <key>New Bugticket</key>
       <value>Neues Bugticket</value>
@@ -5443,6 +5468,9 @@
       <key>Als Attribut ist der Name aus lib_frame z.B. 'ORG' 'PERS' 'OFFER' etc. zu verwenden.</key>
       <value>Als Attribut ist der Name aus lib_frame z.B. 'ORG' 'PERS' 'OFFER' etc. zu verwenden.</value>
     </entry>
+    <entry>
+      <key>Support Tickets</key>
+    </entry>
     <entry>
       <key>Handcraft</key>
       <value>Handwerk</value>
@@ -5491,6 +5519,9 @@
       <key>Quality problem customer</key>
       <value>Qualitätsproblem Kunde</value>
     </entry>
+    <entry>
+      <key>Relation types</key>
+    </entry>
     <entry>
       <key>Wine</key>
       <value>Wein</value>
@@ -5971,7 +6002,7 @@
     </entry>
     <entry>
       <key>Support Ticket</key>
-      <value>Support Ticket</value>
+      <value>Supportticket</value>
     </entry>
     <entry>
       <key>Rented car</key>
@@ -6313,6 +6344,29 @@
     <entry>
       <key>Occurrence</key>
     </entry>
+    <entry>
+      <key>Support ticket</key>
+      <value>Supportticket</value>
+    </entry>
+    <entry>
+      <key>no valid phone number</key>
+      <value>keine gültige Telefonnummer</value>
+    </entry>
+    <entry>
+      <key>Prognose</key>
+    </entry>
+    <entry>
+      <key>EntityToFilterParam</key>
+    </entry>
+    <entry>
+      <key>Sender</key>
+    </entry>
+    <entry>
+      <key>parameter</key>
+    </entry>
+    <entry>
+      <key>Test DuplicateSearch</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index 497b292e32a9f1f4da667135718b4c3c474d4a14..6bf4dd13547b5bb362ca517dd2a635d7aec76a1b 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -5062,6 +5062,54 @@
     <entry>
       <key>New Notifications</key>
     </entry>
+    <entry>
+      <key>Forecasts</key>
+    </entry>
+    <entry>
+      <key>Relation types</key>
+    </entry>
+    <entry>
+      <key>Data privacy entries</key>
+    </entry>
+    <entry>
+      <key>Timetracking entries</key>
+    </entry>
+    <entry>
+      <key>Duplicatescans</key>
+    </entry>
+    <entry>
+      <key>Appointments</key>
+    </entry>
+    <entry>
+      <key>Support Tickets</key>
+    </entry>
+    <entry>
+      <key>Members</key>
+    </entry>
+    <entry>
+      <key>Cost entries</key>
+    </entry>
+    <entry>
+      <key>no valid phone number</key>
+    </entry>
+    <entry>
+      <key>Prognose</key>
+    </entry>
+    <entry>
+      <key>EntityToFilterParam</key>
+    </entry>
+    <entry>
+      <key>Sender</key>
+    </entry>
+    <entry>
+      <key>parameter</key>
+    </entry>
+    <entry>
+      <key>Test DuplicateSearch</key>
+    </entry>
+    <entry>
+      <key>Write bulk mail</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/neonContext/CommRestriction/CommRestriction.aod b/neonContext/CommRestriction/CommRestriction.aod
index 4b27ac29d8604030f95e86435e67a6d0249c4c59..e7734b9ca4dcd2913a142c2639a69027dcedc7f8 100644
--- a/neonContext/CommRestriction/CommRestriction.aod
+++ b/neonContext/CommRestriction/CommRestriction.aod
@@ -20,5 +20,9 @@
       <name>c0ffb2e0-0190-47ee-aa0a-e774fe5400fb</name>
       <view>CommRestrictionPreview_view</view>
     </neonViewReference>
+    <neonViewReference>
+      <name>0f29e6bd-f4cb-488f-867f-a65b84ba341f</name>
+      <view>CommRestrictionDrawer_view</view>
+    </neonViewReference>
   </references>
 </neonContext>
diff --git a/neonContext/DSGVO/DSGVO.aod b/neonContext/DSGVO/DSGVO.aod
index 3b01fff52f6de6d910e943d3aace9fd3dcf4a139..06c58cb090b1d6a885e4cf394694a6c55a34fcfc 100644
--- a/neonContext/DSGVO/DSGVO.aod
+++ b/neonContext/DSGVO/DSGVO.aod
@@ -23,5 +23,9 @@
       <name>4cf0e8c3-900a-43f1-a2c0-3f8990644b64</name>
       <view>DSGVOPreview_view</view>
     </neonViewReference>
+    <neonViewReference>
+      <name>5be7aa7b-2b66-41e1-b1f5-f86af1f6e50d</name>
+      <view>DSGVODrawer_view</view>
+    </neonViewReference>
   </references>
 </neonContext>
diff --git a/neonContext/Person/Person.aod b/neonContext/Person/Person.aod
index 07f8c24364ee6b4716b75d392b44c9d5116f9f98..7149d8ce16047f3b015929edca81b215ba0949e4 100644
--- a/neonContext/Person/Person.aod
+++ b/neonContext/Person/Person.aod
@@ -46,5 +46,9 @@
       <name>fc7e2546-b42a-48c0-8670-2d4033ad0598</name>
       <view>PersonTaskAppointment_view</view>
     </neonViewReference>
+    <neonViewReference>
+      <name>296af7da-1994-49a3-a26f-903f29609fae</name>
+      <view>PersonDSGVORestriction_view</view>
+    </neonViewReference>
   </references>
 </neonContext>
diff --git a/neonDashboard/Home/Home.aod b/neonDashboard/Home/Home.aod
index 82a843b819c93a5c5ffbde865c5fefbebd84cf78..35ab0668ed8d136e2b7638171f947fd292674af9 100644
--- a/neonDashboard/Home/Home.aod
+++ b/neonDashboard/Home/Home.aod
@@ -57,8 +57,8 @@
     </neonDashlet>
     <neonDashlet>
       <name>Dashlet5</name>
-      <viewName>ActivityFilter_view</viewName>
-      <configName>InnateActivitiesDashlet</configName>
+      <viewName>NotificationFilter_view</viewName>
+      <configName>neonDashletConfiguration</configName>
       <uiConfiguration>
         <name>uiConfiguration</name>
         <xPos v="1" />
diff --git a/neonView/BulkMailEdit_view/BulkMailEdit_view.aod b/neonView/BulkMailEdit_view/BulkMailEdit_view.aod
index 0f2c9009d08069b40cd8082687e39250ec8c88bc..6f3346a08a1be5d5ebcb37146c2554d55f385a3c 100644
--- a/neonView/BulkMailEdit_view/BulkMailEdit_view.aod
+++ b/neonView/BulkMailEdit_view/BulkMailEdit_view.aod
@@ -37,6 +37,10 @@
           <name>e4ec09c2-3815-4a3b-bce8-c12d5b919b04</name>
           <entityField>SENDER</entityField>
         </entityFieldLink>
+        <entityFieldLink>
+          <name>0a67f430-dbcd-4605-b626-ee6d715ab248</name>
+          <entityField>content</entityField>
+        </entityFieldLink>
       </fields>
     </genericViewTemplate>
   </children>
diff --git a/neonView/CommRestrictionDrawer_view/CommRestrictionDrawer_view.aod b/neonView/CommRestrictionDrawer_view/CommRestrictionDrawer_view.aod
new file mode 100644
index 0000000000000000000000000000000000000000..613e5c7aa4bbe912193d28c49a833965a1be48eb
--- /dev/null
+++ b/neonView/CommRestrictionDrawer_view/CommRestrictionDrawer_view.aod
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.1">
+  <name>CommRestrictionDrawer_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <drawerLayout>
+      <name>layout</name>
+      <layoutCaption>Advertising bans</layoutCaption>
+      <fixedDrawer v="true" />
+    </drawerLayout>
+  </layout>
+  <children>
+    <neonViewReference>
+      <name>fba5fb33-43d4-4885-84ed-9fe5cc367566</name>
+      <entityField>#ENTITY</entityField>
+      <view>CommRestrictionFilter_view</view>
+    </neonViewReference>
+  </children>
+</neonView>
diff --git a/neonView/DSGVODrawer_view/DSGVODrawer_view.aod b/neonView/DSGVODrawer_view/DSGVODrawer_view.aod
new file mode 100644
index 0000000000000000000000000000000000000000..4cbd306684c1fe78b6f0be6c71b876d568addce1
--- /dev/null
+++ b/neonView/DSGVODrawer_view/DSGVODrawer_view.aod
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.1">
+  <name>DSGVODrawer_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <drawerLayout>
+      <name>layout</name>
+      <layoutCaption>Data privacy entries</layoutCaption>
+      <fixedDrawer v="true" />
+    </drawerLayout>
+  </layout>
+  <children>
+    <neonViewReference>
+      <name>61142c4e-e82d-451e-a491-9a71ac0ec5c0</name>
+      <entityField>#ENTITY</entityField>
+      <view>DSGVOFilter_view</view>
+    </neonViewReference>
+  </children>
+</neonView>
diff --git a/neonView/DSGVOFilter_view/DSGVOFilter_view.aod b/neonView/DSGVOFilter_view/DSGVOFilter_view.aod
index 4d681a32b698c7121556367b36cd43c360aa28f1..cbf7906a101dc094904b7b1d329b97a78491062e 100644
--- a/neonView/DSGVOFilter_view/DSGVOFilter_view.aod
+++ b/neonView/DSGVOFilter_view/DSGVOFilter_view.aod
@@ -13,6 +13,10 @@
       <name>Table</name>
       <favoriteActionGroup1>DSGVOActions</favoriteActionGroup1>
       <favoriteActionGroup2>Reports</favoriteActionGroup2>
+      <iconField>#IMAGE</iconField>
+      <titleField>DSGVOTYPE</titleField>
+      <subtitleField>VALUE</subtitleField>
+      <descriptionField>STATUORITYSOURCE</descriptionField>
       <entityField>#ENTITY</entityField>
       <columns>
         <neonTableColumn>
diff --git a/neonView/PersonDSGVORestriction_view/PersonDSGVORestriction_view.aod b/neonView/PersonDSGVORestriction_view/PersonDSGVORestriction_view.aod
new file mode 100644
index 0000000000000000000000000000000000000000..ba8c4846f3577209970fff50c6cc87e9984d3d11
--- /dev/null
+++ b/neonView/PersonDSGVORestriction_view/PersonDSGVORestriction_view.aod
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.1">
+  <name>PersonDSGVORestriction_view</name>
+  <title>Data Privacy</title>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <neonViewReference>
+      <name>e9af5716-946a-4d29-86e3-06c5231838f9</name>
+      <entityField>DSGVOEntries</entityField>
+      <view>DSGVODrawer_view</view>
+    </neonViewReference>
+    <neonViewReference>
+      <name>38199f7b-af85-4576-a6ee-3add0e6761aa</name>
+      <entityField>CommRestrictions</entityField>
+      <view>CommRestrictionDrawer_view</view>
+    </neonViewReference>
+  </children>
+</neonView>
diff --git a/neonView/PersonMain_view/PersonMain_view.aod b/neonView/PersonMain_view/PersonMain_view.aod
index 967701323ccc3808045936898f3c7d5f0986d346..8d0e2c2199b0a60ac43de76991b5ce64d84fa78f 100644
--- a/neonView/PersonMain_view/PersonMain_view.aod
+++ b/neonView/PersonMain_view/PersonMain_view.aod
@@ -29,11 +29,6 @@
       <entityField>ObjectTrees</entityField>
       <view>ObjectTreeFilter_view</view>
     </neonViewReference>
-    <neonViewReference>
-      <name>265efe97-d759-476c-9546-0f339d56474d</name>
-      <entityField>CommRestrictions</entityField>
-      <view>CommRestrictionFilter_view</view>
-    </neonViewReference>
     <neonViewReference>
       <name>c2606a8b-eac1-412e-893d-bb788d4a5b5c</name>
       <entityField>OtherContacts</entityField>
@@ -44,6 +39,11 @@
       <entityField>#ENTITY</entityField>
       <view>PersonTaskAppointment_view</view>
     </neonViewReference>
+    <neonViewReference>
+      <name>c6dad062-2708-4329-bb60-90f8ab482a6c</name>
+      <entityField>#ENTITY</entityField>
+      <view>PersonDSGVORestriction_view</view>
+    </neonViewReference>
     <neonViewReference>
       <name>cf989bf6-3e49-44fc-ba98-322aae377da3</name>
       <entityField>AttributeTree</entityField>
@@ -59,10 +59,5 @@
       <entityField>LogHistoryConsumer</entityField>
       <view>LogHistoryFilter_view</view>
     </neonViewReference>
-    <neonViewReference>
-      <name>fb1dd01e-a3ad-4708-b6a0-d273cbb0b50f</name>
-      <entityField>DSGVOEntries</entityField>
-      <view>DSGVOFilter_view</view>
-    </neonViewReference>
   </children>
 </neonView>
diff --git a/neonView/ProductFilter_view/ProductFilter_view.aod b/neonView/ProductFilter_view/ProductFilter_view.aod
index 87debd2398a051bb5d0ae1e07b08860c86857636..040e29d62f3c5a87281fe8ffa3fb5fe2627d306e 100644
--- a/neonView/ProductFilter_view/ProductFilter_view.aod
+++ b/neonView/ProductFilter_view/ProductFilter_view.aod
@@ -39,7 +39,7 @@
       <columns>
         <neonTableColumn>
           <name>2b03ec87-92a8-44dd-932e-80df160b2c8e</name>
-          <entityField>#IMAGE</entityField>
+          <entityField>PICTURE</entityField>
         </neonTableColumn>
         <neonTableColumn>
           <name>ee627d12-c60c-48c2-a86e-2a144f5853e6</name>
diff --git a/neonView/ProductPreview_view/ProductPreview_view.aod b/neonView/ProductPreview_view/ProductPreview_view.aod
index cbe4e918fa8161d48ac38b5143ddc95c88dcab66..620131972723f1dfc41577e57143c09846aa22e8 100644
--- a/neonView/ProductPreview_view/ProductPreview_view.aod
+++ b/neonView/ProductPreview_view/ProductPreview_view.aod
@@ -1,74 +1,74 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.1">
-  <name>ProductPreview_view</name>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <layout>
-    <headerFooterLayout>
-      <name>layout</name>
-      <header>Header</header>
-    </headerFooterLayout>
-  </layout>
-  <children>
-    <cardViewTemplate>
-      <name>Header</name>
-      <iconField>IMAGE</iconField>
-      <titleField>PRODUCTCODE</titleField>
-      <descriptionField>PRODUCTNAME</descriptionField>
-      <favoriteAction1>newActivity</favoriteAction1>
-      <entityField>#ENTITY</entityField>
-    </cardViewTemplate>
-    <genericViewTemplate>
-      <name>Info</name>
-      <showDrawer v="true" />
-      <drawerCaption>Details</drawerCaption>
-      <entityField>#ENTITY</entityField>
-      <fields>
-        <entityFieldLink>
-          <name>c47d3f86-867d-4bc4-bcc3-6e22ff8efa6d</name>
-          <entityField>GROUPCODEID</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>505cc05b-0497-4baa-81cb-294ec6e1a133</name>
-          <entityField>STATUS</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>bd8e7e33-6fc6-48fe-b9be-931383f4d859</name>
-          <entityField>CONTACT_ID</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>a5a3ecee-059d-4bf2-9654-abe3efd58510</name>
-          <entityField>UNIT</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>abef7fe5-88f6-44fe-af91-38487eb9b750</name>
-          <entityField>ADVERTISING</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>ba604dc5-06b2-44f2-a9b3-c4c3adb9f8f8</name>
-          <entityField>MINSTOCK</entityField>
-        </entityFieldLink>
-      </fields>
-    </genericViewTemplate>
-    <genericViewTemplate>
-      <name>ProductPriceCurrent</name>
-      <showDrawer v="true" />
-      <drawerCaption>Prices</drawerCaption>
-      <entityField>#ENTITY</entityField>
-      <fields>
-        <entityFieldLink>
-          <name>e47628f5-dd89-4a5d-bb39-8edf8dba9e73</name>
-          <entityField>currentPurchasePrice</entityField>
-        </entityFieldLink>
-        <entityFieldLink>
-          <name>da93c159-d0b2-41d4-8ebe-7f28f623356c</name>
-          <entityField>currentSalesPrice</entityField>
-        </entityFieldLink>
-      </fields>
-    </genericViewTemplate>
-    <neonViewReference>
-      <name>cf0f8792-3f4a-435d-b04c-16843e3f1cd4</name>
-      <entityField>MainDocuments</entityField>
-      <view>DocumentList_view</view>
-    </neonViewReference>
-  </children>
-</neonView>
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.1">
+  <name>ProductPreview_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <headerFooterLayout>
+      <name>layout</name>
+      <header>Header</header>
+    </headerFooterLayout>
+  </layout>
+  <children>
+    <cardViewTemplate>
+      <name>Header</name>
+      <iconField>PICTURE</iconField>
+      <titleField>PRODUCTCODE</titleField>
+      <descriptionField>PRODUCTNAME</descriptionField>
+      <favoriteAction1>newActivity</favoriteAction1>
+      <entityField>#ENTITY</entityField>
+    </cardViewTemplate>
+    <genericViewTemplate>
+      <name>Info</name>
+      <showDrawer v="true" />
+      <drawerCaption>Details</drawerCaption>
+      <entityField>#ENTITY</entityField>
+      <fields>
+        <entityFieldLink>
+          <name>c47d3f86-867d-4bc4-bcc3-6e22ff8efa6d</name>
+          <entityField>GROUPCODEID</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>505cc05b-0497-4baa-81cb-294ec6e1a133</name>
+          <entityField>STATUS</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>bd8e7e33-6fc6-48fe-b9be-931383f4d859</name>
+          <entityField>CONTACT_ID</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>a5a3ecee-059d-4bf2-9654-abe3efd58510</name>
+          <entityField>UNIT</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>abef7fe5-88f6-44fe-af91-38487eb9b750</name>
+          <entityField>ADVERTISING</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>ba604dc5-06b2-44f2-a9b3-c4c3adb9f8f8</name>
+          <entityField>MINSTOCK</entityField>
+        </entityFieldLink>
+      </fields>
+    </genericViewTemplate>
+    <genericViewTemplate>
+      <name>ProductPriceCurrent</name>
+      <showDrawer v="true" />
+      <drawerCaption>Prices</drawerCaption>
+      <entityField>#ENTITY</entityField>
+      <fields>
+        <entityFieldLink>
+          <name>e47628f5-dd89-4a5d-bb39-8edf8dba9e73</name>
+          <entityField>currentPurchasePrice</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>da93c159-d0b2-41d4-8ebe-7f28f623356c</name>
+          <entityField>currentSalesPrice</entityField>
+        </entityFieldLink>
+      </fields>
+    </genericViewTemplate>
+    <neonViewReference>
+      <name>cf0f8792-3f4a-435d-b04c-16843e3f1cd4</name>
+      <entityField>MainDocuments</entityField>
+      <view>DocumentList_view</view>
+    </neonViewReference>
+  </children>
+</neonView>
diff --git a/neonView/ProductpricePreview_view/ProductpricePreview_view.aod b/neonView/ProductpricePreview_view/ProductpricePreview_view.aod
index 4353f66b64422eb7aa3d9294f996840ebb2ef4e1..333a0598599facdc33b839ae9ca86bd7cb3916af 100644
--- a/neonView/ProductpricePreview_view/ProductpricePreview_view.aod
+++ b/neonView/ProductpricePreview_view/ProductpricePreview_view.aod
@@ -46,8 +46,9 @@
     <cardViewTemplate>
       <name>Header</name>
       <iconField>IMAGE</iconField>
-      <titleField>PRICELIST</titleField>
+      <titleField>PRODUCT_ID</titleField>
       <entityField>#ENTITY</entityField>
+      <informationField>PRICELIST</informationField>
     </cardViewTemplate>
   </children>
 </neonView>
diff --git a/neonView/SalesprojectMain_view/SalesprojectMain_view.aod b/neonView/SalesprojectMain_view/SalesprojectMain_view.aod
index 417b5820500118dab37b302d9eb113deaf5bf1b8..3556ac02e1adc5008be50897861c8fac15a5235e 100644
--- a/neonView/SalesprojectMain_view/SalesprojectMain_view.aod
+++ b/neonView/SalesprojectMain_view/SalesprojectMain_view.aod
@@ -18,6 +18,7 @@
       <name>673a34c7-5781-4c72-b0c8-944f1e5de9c6</name>
       <entityField>#ENTITY</entityField>
       <view>SalesprojectOverview_view</view>
+      <devices />
     </neonViewReference>
     <neonViewReference>
       <name>d4daa13e-bf57-45e4-af43-d58c04f113f5</name>
diff --git a/neonView/SalesprojectOverview_view/SalesprojectOverview_view.aod b/neonView/SalesprojectOverview_view/SalesprojectOverview_view.aod
index 4e9c59faff337a60051673040caaec51b9c0a1b2..9e2af6aeda280eeddbf1e5ad9e6820794976c45d 100644
--- a/neonView/SalesprojectOverview_view/SalesprojectOverview_view.aod
+++ b/neonView/SalesprojectOverview_view/SalesprojectOverview_view.aod
@@ -18,6 +18,10 @@
       <name>7c365878-0f88-4bc3-aed4-0667951e70af</name>
       <entityField>SalesprojectPhaseMilestones</entityField>
       <view>SalesprojectMilestoneInfo_view</view>
+      <devices>
+        <element>TABLET</element>
+        <element>DESKTOP</element>
+      </devices>
     </neonViewReference>
     <neonViewReference>
       <name>dd0dd64f-1135-46c5-82d7-9d1e67cf4810</name>
diff --git a/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod b/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod
index 54fe69854e9b505bf62586da79e1d9b4e164a95a..a50772588b32d1d7bff35d4f4dd6d20524853196 100644
--- a/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod
+++ b/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod
@@ -65,7 +65,7 @@
     <customStringProperty>
       <name>phoneValidation.url</name>
       <description></description>
-      <property>https://services.aditosoftware.local/services/rest/ws_checkPhoneNumber</property>
+      <property>https://services.de/services/rest/ws_checkPhoneNumber</property>
     </customStringProperty>
     <customStringProperty>
       <name>phoneValidation.user</name>
diff --git a/process/ActivityTask_lib/process.js b/process/ActivityTask_lib/process.js
index 06fb938445a22fd890d2fe46a6224e80705604e8..a9abd6fc7fba12a3746c814f343853e349874422 100644
--- a/process/ActivityTask_lib/process.js
+++ b/process/ActivityTask_lib/process.js
@@ -1,3 +1,4 @@
+import("system.logging");
 import("Binary_lib");
 import("system.vars");
 import("system.util");
diff --git a/process/Attribute_lib/process.js b/process/Attribute_lib/process.js
index 8e7ff14554340776bf774a386b459216f2473195..db9b5170bdb321aebfddd645328bee7173c811bf 100644
--- a/process/Attribute_lib/process.js
+++ b/process/Attribute_lib/process.js
@@ -1,3 +1,4 @@
+import("system.logging");
 import("Context_lib");
 import("system.util");
 import("system.datetime");
@@ -185,9 +186,9 @@ AttributeUtil.hasRelations = function (pAttributeId)
     return db.cell(SqlCondition.begin()
         .andPrepare("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID", pAttributeId)
         .buildSql(
-            "select count(*) = 0 from AB_ATTRIBUTERELATION", "1=2"
+            "select count(*) from AB_ATTRIBUTERELATION", "1=2" //TODO: is there a way exists could be used?
         )
-    ) != "true";
+    ) != "0";
 }
 
 /**
@@ -822,10 +823,17 @@ AttributeUsageUtil.updateChildrenUsages = function (pAttributeId, pOldObjectType
     
     var table = "AB_ATTRIBUTEUSAGE";
     
-    var sqlSelect = "select AB_ATTRIBUTEID, AB_ATTRIBUTEUSAGEID, "
-        + " (select count(*) from AB_ATTRIBUTEUSAGE where AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID and OBJECT_TYPE = '" 
-        + pNewObjectType + "') = 0"
-        + " from AB_ATTRIBUTE left join AB_ATTRIBUTEUSAGE on AB_ATTRIBUTEID = AB_ATTRIBUTE_ID and OBJECT_TYPE = '" + pOldObjectType + "'";
+    var countSubQuery = SqlCondition.begin()
+        .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pNewObjectType)
+        .and("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID")
+        .buildSql("select count(*) from AB_ATTRIBUTEUSAGE");
+    
+    var sqlSelect = SqlBuilder.begin()
+        .select(["AB_ATTRIBUTEID", "AB_ATTRIBUTEUSAGEID", countSubQuery])
+        .from("AB_ATTRIBUTE")
+        .leftJoin("AB_ATTRIBUTEUSAGE", SqlCondition.begin()
+            .andPrepare("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", pOldObjectType)
+            .and("AB_ATTRIBUTEID = AB_ATTRIBUTE_ID"));
     
     var updateCond = SqlCondition.begin();
     
@@ -845,11 +853,13 @@ AttributeUsageUtil.updateChildrenUsages = function (pAttributeId, pOldObjectType
         var condition = SqlCondition.begin()
             .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?")
             .andPrepare("AB_ATTRIBUTE.ATTRIBUTE_PARENT_ID", pAttributeId);
-        var attributes = db.table(condition.buildSql(sqlSelect));
+        var query = sqlSelect.where(condition);
+        var attributes = db.table(query.build());
+        logging.log(JSON.stringify(attributes, null, "\t"))
         
         attributes.forEach(function (row)
         {
-            if (row[1] && row[2] != "true")
+            if (row[1] && row[2] != "0")
                 deleteCond.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID", row[1]);
             else if (row[1])
                 updateCond.orPrepare("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTEUSAGEID", row[1]);
diff --git a/process/Bulkmail_lib/process.js b/process/Bulkmail_lib/process.js
index 5bed96cdc9c355cb7b732e8ddc4ce2ff80a808ae..f262b0fc0ca14ccf163379f82aeb043945bbb8af 100644
--- a/process/Bulkmail_lib/process.js
+++ b/process/Bulkmail_lib/process.js
@@ -1,247 +1,270 @@
-import("system.util");
-import("Contact_lib");
-import("system.datetime");
-import("system.neon");
-import("Employee_lib");
-import("system.vars");
-import("KeywordRegistry_basic");
-import("Sql_lib");
-import("system.db");
-import("DocumentTemplate_lib");
-import("Email_lib");
-import("system.process");
-import("system.notification");
-
-/**
- * functions for bulk mails
- */
-function BulkMailUtils () {}
-
-/**
- * Executes a process to send bulk mails on the server and creates a notification when finished.
- * 
- * @param {String} pBulkMailId id of the bulk mail
- * @param {String} [pUser=currentUser] User that will get the notification, if null (not undefined!), no notification
- *                                      will be created.
- */
-BulkMailUtils.sendBulkMailOnServer = function (pBulkMailId, pUser)
-{
-    if (pUser === undefined)
-        pUser = EmployeeUtils.getCurrentUserId();
-    process.execute("sendBulkMail_serverProcess", 
-        {
-            bulkMailId : pBulkMailId,
-            user : pUser || ""
-        }
-    );
-}
-
-/**
- * Sends a bulk mail. You should only call this function on the server because it
- * can take some time to execute, use BulkMailUtils.sendBulkMailOnServer instead.
- * 
- * @param {String} pBulkMailId id of the bulk mail 
- * 
- * @return {Object} count of sucessful and failed mails 
- */
-BulkMailUtils.sendBulkMail = function (pBulkMailId)
-{
-    //TODO: Mailbridge, Werbesperre beachten
-    
-    var [templateId, subject, emailSender] = db.array(db.ROW, SqlCondition.begin()
-        .andPrepare("BULKMAIL.BULKMAILID", pBulkMailId)
-        .buildSql("select DOCUMENTTEMPLATE_ID, SUBJECT, SENDER from BULKMAIL", "1=2")
-    );
-    var template = BulkMailUtils.getBulkMailTemplate(pBulkMailId, templateId);
-    
-    var recipientData = db.table(SqlCondition.begin()
-        .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
-        .andPrepare("BULKMAILRECIPIENT.STATUS", $KeywordRegistry.bulkMailRecipientStatus$sent(), "# != ?")
-        .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true))
-        .buildSql("select BULKMAILRECIPIENTID, BULKMAILRECIPIENT.CONTACT_ID, '' from BULKMAILRECIPIENT \n\
-            join CONTACT on BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID", "1=2")
-    );
-    var contactIds = recipientData.map(function (e) {return e[1];});
-    var successIds = [];
-    var failedIds = [];
-    var sentDate = vars.get("$sys.date");
-    var mails = template.getReplacedEmailsByContactIds(contactIds);
-    
-    var subjectTemplate = new DocumentTemplate(subject, DocumentTemplate.types.PLAIN);
-    var subjects = subjectTemplate.getReplacedContentByContactIds(contactIds);
-    
-    for (let i = 0, l = recipientData.length; i < l; i++)
-    {
-        let isSuccess = false;
-        let contactId = recipientData[i][1];
-        let email = mails[contactId];
-        if (email !== undefined && recipientData[i][2])
-        {
-            email.toRecipients = [recipientData[i][2]]; //TODO: email address missing
-            email.sender = emailSender;
-            email.subject = subjects[contactId];
-
-            isSuccess = email.send();
-        }
-        if (isSuccess)
-            successIds.push(recipientData[i][0]); //set the recipient status to 'sent'
-        else
-            failedIds.push(recipientData[i][0]); //set the recipient status to 'failed'
-    }
-    db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$sent(), sentDate], 
-        SqlCondition.begin()
-            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", successIds)
-            .build("1=2")
-    );
-    db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$failed(), sentDate], 
-        SqlCondition.begin()
-            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", failedIds)
-            .build("1=2")
-    );
-        
-    db.updateData("BULKMAIL", ["STATUS"], null, [$KeywordRegistry.bulkMailStatus$sent()], 
-        SqlCondition.equals("BULKMAIL.BULKMAILID", pBulkMailId, "1=2"));
-        
-    return {
-        sucessful : successIds.length,
-        failed : failedIds.length
-    };
-}
-
-
-BulkMailUtils.openAddRecipientView = function (pContactIds)
-{
-    var params = {
-        "ContactIds_param" : pContactIds
-    };
-    neon.openContext("BulkMailAddRecipients", "BulkMailAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
-}
-
-/**
- * deletes all bulk mail recipients that have a commrestriction for emails
- * 
- * @param {String} pBulkMailId
- */
-BulkMailUtils.removeCommRestrictionRecipients = function (pBulkMailId)
-{
-    var recipientIds = db.array(db.COLUMN, SqlBuilder.begin()
-        .select("BULKMAILRECIPIENTID")
-        .from("BULKMAILRECIPIENT")
-        .join("CONTACT", SqlCondition.begin()
-            .and("BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
-            .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail())))
-        .where(SqlCondition.begin()
-            .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId))
-        .build());
-
-    if (recipientIds.length)
-    {
-        db.deleteData("BULKMAILRECIPIENT", SqlCondition.begin()
-            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", recipientIds)
-            .build("1=2"));
-    }
-}
-
-/**
- * adds recipients to a bulkmail
- * 
- * @param {String} pBulkMailId bulk mail id
- * @param {String[]} pContactIds contact ids of the recipients
- */
-BulkMailUtils.addRecipients = function (pBulkMailId, pContactIds)
-{
-    var columns = [
-        "BULKMAILRECIPIENTID",
-        "BULKMAIL_ID",
-        "CONTACT_ID",
-        "STATUS"
-    ];
-    var inserts = [];
-    for (let i = 0, l = pContactIds.length; i < l; i++)
-    {
-        inserts.push(["BULKMAILRECIPIENT", columns, null, [util.getNewUUID(), pBulkMailId, pContactIds[i], $KeywordRegistry.bulkMailRecipientStatus$pending()]]);
-    }
-    db.inserts(inserts);
-}
-
-/**
- * Loads the document template of a bulk mail. If the bulk mail itself has a
- * template, it is preferred over the documentTemplate-id.
- * 
- * @param {String} pBulkMailId bulkmail id
- * @param {String} pDocumentTemplateId documentTemplate id
- * 
- * @return {DocumentTemplate} the document template, null if no content was found.
- */
-BulkMailUtils.getBulkMailTemplate = function (pBulkMailId, pDocumentTemplateId)
-{
-    var template = DocumentTemplate.loadTemplate(pBulkMailId, "BULKMAIL");
-    if (!template.type)
-        template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
-    return template;
-}
-
-BulkMailUtils.isRecipient = function (pBulkMailId, pContactId)
-{
-    return db.cell(SqlCondition.begin()
-        .andPrepare("BULKMAILRECIPIENT.CONTACT_ID", pContactId)
-        .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
-        .buildSql("select count(*) = 0 from BULKMAILRECIPIENT")
-    ) != "true";
-}
-
-function SerialLetterUtils () {}
-
-/**
- * adds recipients to a serial letter
- * 
- * @param {String} pSerialLetterId serial letter id
- * @param {String[]} pContactIds contact ids of the recipients
- */
-SerialLetterUtils.addRecipients = function (pSerialLetterId, pContactIds)
-{
-    var columns = [
-        "LETTERRECIPIENTID",
-        "SERIALLETTER_ID",
-        "CONTACT_ID"
-    ];
-    var inserts = [];
-    for (let i = 0, l = pContactIds.length; i < l; i++)
-    {
-        inserts.push(["LETTERRECIPIENT", columns, null, [util.getNewUUID(), pSerialLetterId, pContactIds[i]]]);
-    }
-    db.inserts(inserts);
-}
-
-
-SerialLetterUtils.openAddRecipientView = function (pContactIds)
-{
-    var params = {
-        "ContactIds_param" : pContactIds
-    };
-    neon.openContext("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
-}
-
-/**
- * executes a server process that builds a serial letter
- * 
- * @param {String} pSerialLetterId serial letter id
- * @param {String[]} [pRecipientIds] Letter recipient ids of that should be used.
- *                                    If omitted, all recipients of the letter will be used.
- */
-SerialLetterUtils.buildSerialLetter = function (pSerialLetterId, pRecipientIds)
-{
-    process.execute("buildSerialLetter_serverProcess", {
-        "serialLetterId" : pSerialLetterId,
-        "recipientIds" : JSON.stringify(pRecipientIds)
-    });
-}
-
-SerialLetterUtils.isRecipient = function (pSerialLetterId, pContactId)
-{
-    return db.cell(SqlCondition.begin()
-        .andPrepare("LETTERRECIPIENT.CONTACT_ID", pContactId)
-        .andPrepare("LETTERRECIPIENT.SERIALLETTER_ID", pSerialLetterId)
-        .buildSql("select count(*) = 0 from LETTERRECIPIENT")
-    ) != "true";
+import("system.util");
+import("Contact_lib");
+import("system.datetime");
+import("system.neon");
+import("Employee_lib");
+import("system.vars");
+import("KeywordRegistry_basic");
+import("Sql_lib");
+import("system.db");
+import("DocumentTemplate_lib");
+import("Communication_lib");
+import("Email_lib");
+import("system.process");
+import("system.notification");
+
+/**
+ * functions for bulk mails
+ */
+function BulkMailUtils () {}
+
+/**
+ * Executes a process to send bulk mails on the server and creates a notification when finished.
+ * 
+ * @param {String} pBulkMailId id of the bulk mail
+ * @param {String} [pUser=currentUser] User that will get the notification, if null (not undefined!), no notification
+ *                                      will be created.
+ */
+BulkMailUtils.sendBulkMailOnServer = function (pBulkMailId, pUser)
+{
+    if (pUser === undefined)
+        pUser = EmployeeUtils.getCurrentUserId();
+    process.execute("sendBulkMail_serverProcess", 
+        {
+            bulkMailId : pBulkMailId,
+            user : pUser || ""
+        }
+    );
+}
+
+/**
+ * Sends a bulk mail. You should only call this function on the server because it
+ * can take some time to execute, use BulkMailUtils.sendBulkMailOnServer instead.
+ * 
+ * @param {String} pBulkMailId id of the bulk mail 
+ * 
+ * @return {Object} count of sucessful and failed mails 
+ */
+BulkMailUtils.sendBulkMail = function (pBulkMailId)
+{
+    var [templateId, subject, emailSender] = db.array(db.ROW, SqlCondition.begin()
+        .andPrepare("BULKMAIL.BULKMAILID", pBulkMailId)
+        .buildSql("select DOCUMENTTEMPLATE_ID, SUBJECT, SENDER from BULKMAIL", "1=2")
+    );
+    var template = BulkMailUtils.getBulkMailTemplate(pBulkMailId, templateId);
+    
+    var sql = SqlBuilder.begin()
+        .select("BULKMAILRECIPIENTID, BULKMAILRECIPIENT.CONTACT_ID, (" + CommUtil.getStandardSubSqlMail() + ")")
+        .from("BULKMAILRECIPIENT")
+        .join("CONTACT", "BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
+        .where(SqlCondition.begin()
+            .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
+            .andPrepare("BULKMAILRECIPIENT.STATUS", $KeywordRegistry.bulkMailRecipientStatus$sent(), "# != ?")
+            .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true)))
+        .build();
+        
+    var recipientData = db.table(sql);
+    var contactIds = recipientData.map(function (e) {return e[1];});
+    var successIds = [];
+    var failedIds = [];
+    var sentDate = vars.get("$sys.date");
+    var mails = template.getReplacedEmailsByContactIds(contactIds);
+    
+    var subjectTemplate = new DocumentTemplate(subject, DocumentTemplate.types.PLAIN);
+    var subjects = subjectTemplate.getReplacedContentByContactIds(contactIds);
+    
+    for (let i = 0, l = recipientData.length; i < l; i++)
+    {
+        let isSuccess = false;
+        let contactId = recipientData[i][1];
+        let email = mails[contactId];
+        if (email !== undefined && recipientData[i][2])
+        {
+            email.toRecipients = [recipientData[i][2]];
+            email.sender = emailSender;
+            email.subject = subjects[contactId];
+
+            isSuccess = email.send();
+        }
+        if (isSuccess)
+            successIds.push(recipientData[i][0]); //set the recipient status to 'sent'
+        else
+            failedIds.push(recipientData[i][0]); //set the recipient status to 'failed'
+    }
+    db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$sent(), sentDate], 
+        SqlCondition.begin()
+            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", successIds)
+            .build("1=2")
+    );
+    db.updateData("BULKMAILRECIPIENT", ["STATUS", "SENTDATE"], null, [$KeywordRegistry.bulkMailRecipientStatus$failed(), sentDate], 
+        SqlCondition.begin()
+            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", failedIds)
+            .build("1=2")
+    );
+        
+    db.updateData("BULKMAIL", ["STATUS"], null, [$KeywordRegistry.bulkMailStatus$sent()], 
+        SqlCondition.equals("BULKMAIL.BULKMAILID", pBulkMailId, "1=2"));
+        
+    return {
+        sucessful : successIds.length,
+        failed : failedIds.length
+    };
+}
+
+
+BulkMailUtils.openAddRecipientView = function (pContactIds)
+{
+    var params = {
+        "ContactIds_param" : pContactIds
+    };
+    neon.openContext("BulkMailAddRecipients", "BulkMailAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
+}
+
+/**
+ * deletes all bulk mail recipients that have a commrestriction for emails
+ * 
+ * @param {String} pBulkMailId
+ */
+BulkMailUtils.removeCommRestrictionRecipients = function (pBulkMailId)
+{
+    var recipientIds = db.array(db.COLUMN, SqlBuilder.begin()
+        .select("BULKMAILRECIPIENTID")
+        .from("BULKMAILRECIPIENT")
+        .join("CONTACT", SqlCondition.begin()
+            .and("BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID")
+            .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail())))
+        .where(SqlCondition.begin()
+            .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId))
+        .build());
+
+    if (recipientIds.length)
+    {
+        db.deleteData("BULKMAILRECIPIENT", SqlCondition.begin()
+            .andIn("BULKMAILRECIPIENT.BULKMAILRECIPIENTID", recipientIds)
+            .build("1=2"));
+    }
+}
+
+/**
+ * adds recipients to a bulkmail
+ * 
+ * @param {String} pBulkMailId bulk mail id
+ * @param {String[]} pContactIds contact ids of the recipients
+ */
+BulkMailUtils.addRecipients = function (pBulkMailId, pContactIds)
+{
+    var columns = [
+        "BULKMAILRECIPIENTID",
+        "BULKMAIL_ID",
+        "CONTACT_ID",
+        "STATUS"
+    ];
+    var inserts = [];
+    for (let i = 0, l = pContactIds.length; i < l; i++)
+    {
+        inserts.push(["BULKMAILRECIPIENT", columns, null, [util.getNewUUID(), pBulkMailId, pContactIds[i], $KeywordRegistry.bulkMailRecipientStatus$pending()]]);
+    }
+    db.inserts(inserts);
+}
+
+/**
+ * Loads the document template of a bulk mail. If the bulk mail itself has a
+ * template, it is preferred over the documentTemplate-id.
+ * 
+ * @param {String} pBulkMailId bulkmail id
+ * @param {String} pDocumentTemplateId documentTemplate id
+ * 
+ * @return {DocumentTemplate} the document template, null if no content was found.
+ */
+BulkMailUtils.getBulkMailTemplate = function (pBulkMailId, pDocumentTemplateId)
+{
+    var template = DocumentTemplate.loadTemplate(pBulkMailId, "BULKMAIL");
+    if (!template.type)
+        template = DocumentTemplate.loadTemplate(pDocumentTemplateId);
+    return template;
+}
+
+BulkMailUtils.isRecipient = function (pBulkMailId, pContactId)
+{
+    return db.cell(SqlCondition.begin()
+        .andPrepare("BULKMAILRECIPIENT.CONTACT_ID", pContactId)
+        .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId)
+        .buildSql("select count(*) from BULKMAILRECIPIENT") //TODO: is there a way exists could be used?
+    ) != "0";
+}
+
+BulkMailUtils.newBulkMail = function (pRecipients)
+{
+    var params = {
+        "PresetRecipients_param" : JSON.stringify(pRecipients)
+    };
+    neon.openContext("BulkMail", "BulkMailEdit_view", null, neon.OPERATINGSTATE_NEW, params);
+}
+
+BulkMailUtils.filterNewRecipients = function (pBulkMailId, pContactIds)
+{
+    var existsQuery = "not exists(select BULKMAILRECIPIENTID from BULKMAILRECIPIENT where BULKMAILRECIPIENT.CONTACT_ID = CONTACT.CONTACTID and # = ?)";
+    var query = SqlCondition.begin()
+        .andIn("CONTACT.CONTACTID", pContactIds)
+        .andPrepare("BULKMAILRECIPIENT.BULKMAIL_ID", pBulkMailId, existsQuery) //only add contacts that aren't already recipients
+        .andSqlCondition(ContactUtils.getCommRestrictionCondition($KeywordRegistry.communicationMediumCampaign$mail(), true))  //check if there's a commrestriction
+        .buildSql("select CONTACTID from CONTACT");
+
+    return db.array(db.COLUMN, query); 
+}
+
+function SerialLetterUtils () {}
+
+/**
+ * adds recipients to a serial letter
+ * 
+ * @param {String} pSerialLetterId serial letter id
+ * @param {String[]} pContactIds contact ids of the recipients
+ */
+SerialLetterUtils.addRecipients = function (pSerialLetterId, pContactIds)
+{
+    var columns = [
+        "LETTERRECIPIENTID",
+        "SERIALLETTER_ID",
+        "CONTACT_ID"
+    ];
+    var inserts = [];
+    for (let i = 0, l = pContactIds.length; i < l; i++)
+    {
+        inserts.push(["LETTERRECIPIENT", columns, null, [util.getNewUUID(), pSerialLetterId, pContactIds[i]]]);
+    }
+    db.inserts(inserts);
+}
+
+
+SerialLetterUtils.openAddRecipientView = function (pContactIds)
+{
+    var params = {
+        "ContactIds_param" : pContactIds
+    };
+    neon.openContext("SerialLetterAddRecipients", "SerialLetterAddRecipientsEdit_view", null, neon.OPERATINGSTATE_NEW, params);
+}
+
+/**
+ * executes a server process that builds a serial letter
+ * 
+ * @param {String} pSerialLetterId serial letter id
+ * @param {String[]} [pRecipientIds] Letter recipient ids of that should be used.
+ *                                    If omitted, all recipients of the letter will be used.
+ */
+SerialLetterUtils.buildSerialLetter = function (pSerialLetterId, pRecipientIds)
+{
+    process.execute("buildSerialLetter_serverProcess", {
+        "serialLetterId" : pSerialLetterId,
+        "recipientIds" : JSON.stringify(pRecipientIds)
+    });
+}
+
+SerialLetterUtils.isRecipient = function (pSerialLetterId, pContactId)
+{
+    return db.cell(SqlCondition.begin()
+        .andPrepare("LETTERRECIPIENT.CONTACT_ID", pContactId)
+        .andPrepare("LETTERRECIPIENT.SERIALLETTER_ID", pSerialLetterId)
+        .buildSql("select count(*) from LETTERRECIPIENT") //TODO: is there a way exists could be used?
+    ) != "0";
 }
\ No newline at end of file
diff --git a/process/Communication_lib/process.js b/process/Communication_lib/process.js
index a22c886fc5f2c8c30ad92dc1c01f14e2011a0b7c..fa127e6087e4e6d95e6798b91f58bc01116fc6ef 100644
--- a/process/Communication_lib/process.js
+++ b/process/Communication_lib/process.js
@@ -198,8 +198,8 @@ function CommValidationUtil() {}
 CommValidationUtil.makeValidationFn = function (commCategory)
 {
     var callbackFn;
-
-    switch (commCategory) {
+    
+    switch (commCategory.trim()) {
         case "EMAIL":
             callbackFn = function (addrValue){
                 if (!mail.isValidMailAddress(addrValue, true))
@@ -216,11 +216,12 @@ CommValidationUtil.makeValidationFn = function (commCategory)
             break;
         case "TELEPHONE":
             callbackFn = function (addrValue, ext){
-                var country = null;
-                if (addrValue[0] != "+") //if the number starts with a country-identifier (e.g. +49) no country needs to be specified
-                    country = ext.countryCode;
-//                if (!cti.isValidPhoneNumber(addrValue, country))//TODO: enable JDito-methods
-//                    return translate.text("no valid phone number");
+                var country = ext.countryCode;
+                
+                if (!cti.isValidPhoneNumber(addrValue, false, country)) {
+                    return translate.text("no valid phone number");
+                }
+                    
                 return null;
             }
             break;
diff --git a/process/Contact_lib/process.js b/process/Contact_lib/process.js
index 63a47219b9f5b47f3d95e6dceae2970d9ad83cfd..88f2a5b4878bd8576cde9474cba585bc7401ffb0 100644
--- a/process/Contact_lib/process.js
+++ b/process/Contact_lib/process.js
@@ -456,9 +456,9 @@ ContactUtils.hasCommRestriction = function (pContactId, pMedium, pStartDate)
     var query = SqlCondition.begin()
         .andPrepare("CONTACT.CONTACTID", pContactId)
         .andSqlCondition(ContactUtils.getCommRestrictionCondition(pMedium, false, pStartDate))
-        .buildSql("select count(*) = 0 from CONTACT", "1=2");
+        .buildSql("select count(*) from CONTACT", "1=2"); //TODO: is there a way exists could be used?
 
-    return db.cell(query) != "true";
+    return db.cell(query) != "0";
 }
 
 /**
diff --git a/process/DataPrivacy_lib/process.js b/process/DataPrivacy_lib/process.js
index 78656bb581dc27cb7908a9dc6b0a3e6115e8f83d..2a90429564990b9c7e179f19ee788fa19c7d5398 100644
--- a/process/DataPrivacy_lib/process.js
+++ b/process/DataPrivacy_lib/process.js
@@ -21,6 +21,27 @@ import("Report_lib");
 import("Contact_lib");
 import("Address_lib");
 
+/************************************************
+ ******************READ CAREFULLY****************
+ ************************************************
+ *
+ * Steps for adding a privacy field:
+ * - create Keyword Containername: "DSGVOType"
+ * - Add to list in DataPrivacyType.get - function with the same name as the keyword keyid. (see DataPrivacyType for all possible parameters)
+ *  e.g. if keyword-keyid is "TYPE_HOBBY" then add:
+ *  TYPE_HOBBY: new DataPrivacyType("TYPE_HOBBY", _getHobby),
+ * - create a function for collecting the data (in this example _getHobby(...)) and put it inside of DataPrivacyType.get() {...}
+ *   like the other ones
+ * - the function takes two parameters: 
+ *   * pContactId: The contact for which the data should be selected.
+ *                 This param is always provided.
+ *   * pUid: A uid for your type. If the DSGVO-entity just needs the data for one dataset it calls the function with this param. 
+ *           In most cases it is undefined.
+ * - the function can use any way to load the data. It has to return an array of objects which contain a "value" and a "id".
+ *   (take the already provided functions as reference)
+ * - add the DataPrivacyUtils.notifyNeedDataPrivacyUpdate() function everywhere where your datasource is updated.
+ */
+
 /**
  * 
  * Do not create new instances anywhere else than inside of the get-function!
@@ -37,7 +58,7 @@ function DataPrivacyType(pKeyId, pGetValuesCallback, pFormatAsDate)
 
 /**
  * NOTE: The Key in the cache has to be the same as the first argument (pKeyId)
- * NOTE2: These Types have to exist also as Keyord!
+ * NOTE2: These Types have to exist also as Keyword!
  * 
  * get all possible DataPrivacyTypes or one specific
  * @param {String} [pKey=undefined] if provided, this function returns only the DataPrivacyTypes with this key
@@ -190,7 +211,7 @@ DataPrivacyType.get = function(pKey)
         return attributeData.map(function(pAttr)
         {
             return {
-                value: pAttr[1] + ": " + pAttr[2],
+                value: pAttr[1] + ": " + translate.text(pAttr[2]),
                 id: pAttr[0]
             }
         });
@@ -212,7 +233,7 @@ DataPrivacyUtils.getDSGVO = function(pContactId, pFilterCond)
     
     var select =    "DSGVOID," +               // 0
                     "CONTACT_ID," +            // 1
-                    "DSGVOTYPE," +                  // 2
+                    "DSGVOTYPE," +             // 2
                     "ROW_ID," +                // 3
                     "''," +                    // 4 - dummy for value
                     "STATUORITYSOURCE," +      // 5
@@ -296,7 +317,7 @@ DataPrivacyUtils.collectAll = function(pContactId, pFilterCond)
                     "",             // "DATE_EDIT," +             // 9
                     currentUser,    // "USER_NEW," +              // 10
                     "",             // "USER_EDIT "               // 11
-                    KeywordUtils.getViewValue($KeywordRegistry.dsgvoType(), StringUtils.toChar36(dsgvotype.key)), // 12
+                    KeywordUtils.getViewValue($KeywordRegistry.dsgvoType(), StringUtils.pad36(dsgvotype.key)), // 12
                 ])
             }
         });
diff --git a/process/DocumentTemplate_lib/process.js b/process/DocumentTemplate_lib/process.js
index 898b573bcaa2faf078b657260e33cad21d2011b7..dbcfb36a91297076174750b3f86105e75e375448 100644
--- a/process/DocumentTemplate_lib/process.js
+++ b/process/DocumentTemplate_lib/process.js
@@ -121,15 +121,16 @@ DocumentTemplate.prototype._getRequiredPlaceholders = function ()
     return usedPlaceholders; 
 }
 
-/**
+/** 
  * Returns the template content with replaced placeholders by choosing the right
  * replace function for the type.
  * 
  * @param {Object} pReplacements map, the structure is {placeholder : value}
+ * @param {boolean} pDecoded if the replaced content should be not base64 encoded
  * 
  * @return {String} the replaced content
  */
-DocumentTemplate.prototype.getReplacedContent = function (pReplacements)
+DocumentTemplate.prototype.getReplacedContent = function (pReplacements, pDecoded)
 {
     switch (this.type)
     {
@@ -137,8 +138,11 @@ DocumentTemplate.prototype.getReplacedContent = function (pReplacements)
             for (let i in pReplacements)
                 pReplacements[i] = text.text2html(pReplacements[i], false);
         case DocumentTemplate.types.TXT:
-            let decodedContent = util.decodeBase64String(this.content)
-            return DocumentTemplate._replaceText(decodedContent, pReplacements);
+            let decodedContent = util.decodeBase64String(this.content);
+            let encodedContent = DocumentTemplate._replaceText(decodedContent, pReplacements);
+            if (!pDecoded)
+                encodedContent = util.encodeBase64String(encodedContent);
+            return encodedContent;
         case DocumentTemplate.types.EML:
             return this._getReplacedEML(pReplacements);
         case DocumentTemplate.types.ODT:
@@ -158,7 +162,9 @@ DocumentTemplate.prototype.getReplacedContent = function (pReplacements)
 DocumentTemplate.prototype.getReplacedContentByContactId = function (pContactId) 
 {
     var replacements = this._getReplacementsByContactIds([pContactId]); 
-    return this.getReplacedContent(replacements[pContactId]);
+    var content = this.getReplacedContent(replacements[pContactId]);
+    
+    return content;
 }
 
 /**
@@ -245,7 +251,7 @@ DocumentTemplate.prototype.getReplacedEmailsByContactIds = function (pContactIds
         }
         else
         {
-            let body = this.getReplacedContent(replacements[contactId]);
+            let body = this.getReplacedContent(replacements[contactId], true);
             if (this.type == DocumentTemplate.types.TXT || this.type == DocumentTemplate.types.PLAIN)
                 body = text.text2html(body, false);
             emailObj[contactId] = new Email(null, null, null, body);
@@ -442,7 +448,7 @@ DocumentTemplate.prototype._getReplacedDOCX = function (pReplacements)
     var replacements = {};
     for (let placeholder in pReplacements)  //removes the prefix and postfix, the process needs it like this
         replacements[placeholder.slice(3, -3)] = pReplacements[placeholder];
-    
+
     //this is executed as a process because of better performance
     var documentData = process.execute("getDocxDocument_serverProcess", {
         templateb64: this.content,
diff --git a/process/Email_lib/process.js b/process/Email_lib/process.js
index 85ee436af9830e224fc709b0e1fb974725ede06f..eeb0b8a3124b77105f62e7808fd46f93653d716a 100644
--- a/process/Email_lib/process.js
+++ b/process/Email_lib/process.js
@@ -250,6 +250,7 @@ Email.prototype.send = function ()
     }
     catch (ex)
     {
+        logging.log(ex);
         return false;
     }
 }
\ No newline at end of file
diff --git a/process/KeywordRegistry_basic/process.js b/process/KeywordRegistry_basic/process.js
index 86ecfcad1577c40ea91fe3eebc71bfe5097dd91d..0b30594ebabee3603c112641ef3857607d332ab3 100644
--- a/process/KeywordRegistry_basic/process.js
+++ b/process/KeywordRegistry_basic/process.js
@@ -16,16 +16,17 @@
  * $KeywordRegistry.activityDirection()
  */
 function $KeywordRegistry(){}
-$KeywordRegistry._autoPad = function(pKey){return pKey + " ".repeat(Math.max(0, 36-pKey.length))};
+// this function can also be found as StringUtils.pad36() in Util_lib and is just here to avoid an import because this registry is heavily used.
+$KeywordRegistry._autoPad = function(pKey){return (pKey + "                                    ").slice(0, 36)}; 
 
 $KeywordRegistry.attributeType = function(){return "AttributeType";};
 $KeywordRegistry.keywordAttributeType = function(){return "KeywordAttributeType";};
 $KeywordRegistry.contractPayment = function(){return "ContractPayment";};
 
 $KeywordRegistry.contractStatus = function(){return "ContractStatus";};
-$KeywordRegistry.contractState$validLimited = function(){return "CONTRACTSTATVALIDLI                 ";};
-$KeywordRegistry.contractState$validUnlimited = function(){return "CONTRACTSTATVALIDUNLI               ";};
-$KeywordRegistry.contractState$notSigned = function(){return "CONTRACTSTATSIGN                    ";};
+$KeywordRegistry.contractState$validLimited = function(){return $KeywordRegistry._autoPad("CONTRACTSTATVALIDLI");};
+$KeywordRegistry.contractState$validUnlimited = function(){return $KeywordRegistry._autoPad("CONTRACTSTATVALIDUNLI");};
+$KeywordRegistry.contractState$notSigned = function(){return $KeywordRegistry._autoPad("CONTRACTSTATSIGN");};
 
 $KeywordRegistry.contractType = function(){return "ContractType";};
 
@@ -37,44 +38,44 @@ $KeywordRegistry.contactStatus = function(){return "ContactStatus";};
 $KeywordRegistry.contactStatus$active = function(){return $KeywordRegistry._autoPad("CONTACTSTATACTIVE");};
 
 $KeywordRegistry.currency = function(){return "Currency";};
-$KeywordRegistry.currency$eur = function(){return "EUR                                 ";};
+$KeywordRegistry.currency$eur = function(){return $KeywordRegistry._autoPad("EUR");};
 
 $KeywordRegistry.productGroupcode = function(){return "ProductGroupcode";};
 
 $KeywordRegistry.offerStatus = function(){return "OfferStatus";};
-$KeywordRegistry.offerStatus$open = function(){return "OFFERSTATOPEN                       ";};
-$KeywordRegistry.offerStatus$checked = function(){return "OFFERSTATCHECK                      ";};
-$KeywordRegistry.offerStatus$sent = function(){return "OFFERSTATSENT                       ";};
-$KeywordRegistry.offerStatus$won = function(){return "OFFERSTATWON                        ";};
-$KeywordRegistry.offerStatus$lost = function(){return "OFFERSTATLOST                       ";};
+$KeywordRegistry.offerStatus$open = function(){return $KeywordRegistry._autoPad("OFFERSTATOPEN");};
+$KeywordRegistry.offerStatus$checked = function(){return $KeywordRegistry._autoPad("OFFERSTATCHECK");};
+$KeywordRegistry.offerStatus$sent = function(){return $KeywordRegistry._autoPad("OFFERSTATSENT");};
+$KeywordRegistry.offerStatus$won = function(){return $KeywordRegistry._autoPad("OFFERSTATWON");};
+$KeywordRegistry.offerStatus$lost = function(){return $KeywordRegistry._autoPad("OFFERSTATLOST");};
 
 $KeywordRegistry.organisationType = function(){return "OrganisationType";};
-$KeywordRegistry.organisationType$manufacturer = function(){return "ORGMANUF";};
-$KeywordRegistry.organisationType$competitor = function(){return "ORGCOMP";};
+$KeywordRegistry.organisationType$manufacturer = function(){return $KeywordRegistry._autoPad("ORGMANUF");};
+$KeywordRegistry.organisationType$competitor = function(){return $KeywordRegistry._autoPad("ORGCOMP");};
 
 $KeywordRegistry.personGender = function(){return "PersonGender";};
 
 $KeywordRegistry.taskStatus = function(){return "TaskStatus";};
-$KeywordRegistry.taskStatus$new = function(){return "NEW                                 ";};
-$KeywordRegistry.taskStatus$unassigned = function(){return "UNASSIGNED                          ";};
-$KeywordRegistry.taskStatus$assigned = function(){return "ASSIGNED                            ";};
-$KeywordRegistry.taskStatus$inProgress = function(){return "IN-PROGRESS                         ";};
-$KeywordRegistry.taskStatus$waiting = function(){return "WAITING                             ";};
-$KeywordRegistry.taskStatus$ended = function(){return "ENDED                               ";};
-$KeywordRegistry.taskStatus$customerChecks = function(){return "CUSTOMER-CHECKS                     ";};
+$KeywordRegistry.taskStatus$new = function(){return $KeywordRegistry._autoPad("NEW");};
+$KeywordRegistry.taskStatus$unassigned = function(){return $KeywordRegistry._autoPad("UNASSIGNED");};
+$KeywordRegistry.taskStatus$assigned = function(){return $KeywordRegistry._autoPad("ASSIGNED");};
+$KeywordRegistry.taskStatus$inProgress = function(){return $KeywordRegistry._autoPad("IN-PROGRESS");};
+$KeywordRegistry.taskStatus$waiting = function(){return $KeywordRegistry._autoPad("WAITING");};
+$KeywordRegistry.taskStatus$ended = function(){return $KeywordRegistry._autoPad("ENDED");};
+$KeywordRegistry.taskStatus$customerChecks = function(){return $KeywordRegistry._autoPad("CUSTOMER-CHECKS");};
 
 $KeywordRegistry.taskType = function(){return "TaskType";};
-$KeywordRegistry.taskType$task = function(){return "TASK                                ";};
-$KeywordRegistry.taskType$ticket = function(){return "TICKET                              ";};
+$KeywordRegistry.taskType$task = function(){return $KeywordRegistry._autoPad("TASK");};
+$KeywordRegistry.taskType$ticket = function(){return $KeywordRegistry._autoPad("TICKET");};
 
 $KeywordRegistry.ticketType = function(){return "TicketType";};
-$KeywordRegistry.ticketType$supportTicket = function(){return "SUPPORTTICKET                       ";};
+$KeywordRegistry.ticketType$supportTicket = function(){return $KeywordRegistry._autoPad("SUPPORTTICKET");};
 
 $KeywordRegistry.productPricelist = function(){return "ProductPricelist";};
-$KeywordRegistry.productPricelist$standardList = function(){return "PRICELISTDEFAULT                    ";};
+$KeywordRegistry.productPricelist$standardList = function(){return $KeywordRegistry._autoPad("PRICELISTDEFAULT");};
 
 $KeywordRegistry.quantityUnit = function(){return "QuantityUnit";};
-$KeywordRegistry.quantityUnit$pieces = function(){return "QUANTITYPIECES";};
+$KeywordRegistry.quantityUnit$pieces = function(){return $KeywordRegistry._autoPad("QUANTITYPIECES");};
 
 $KeywordRegistry.MemberRole = function(){return "MemberRole";};
 $KeywordRegistry.salesprojectSource = function(){return "SalesprojectSource";};
@@ -84,11 +85,11 @@ $KeywordRegistry.stockWarehouse = function(){return "StockWarehouse";};
 $KeywordRegistry.salesprojectProbability = function(){return "SalesprojectProbability";};
 
 $KeywordRegistry.activityCategory = function(){return "ActivityCategory";};
-$KeywordRegistry.activityCategory$mail = function(){return "MAIL                                ";};
+$KeywordRegistry.activityCategory$mail = function(){return $KeywordRegistry._autoPad("MAIL");};
 
 $KeywordRegistry.addressType = function(){return "AddressType";};
-$KeywordRegistry.addressType$private = function(){return "HOMEADDR";};
-$KeywordRegistry.addressType$office = function(){return "OFFICEADDR";};
+$KeywordRegistry.addressType$private = function(){return $KeywordRegistry._autoPad("HOMEADDR");};
+$KeywordRegistry.addressType$office = function(){return $KeywordRegistry._autoPad("OFFICEADDR");};
 
 $KeywordRegistry.offerProbability = function(){return "OfferProbability";};
 $KeywordRegistry.communicationMedium = function(){return "CommunicationMedium";};
@@ -97,24 +98,24 @@ $KeywordRegistry.salesprojectWeakness = function(){return "SalesprojectWeakness"
 $KeywordRegistry.salesprojectStrenght = function(){return "SalesprojectStrenght";};
 
 $KeywordRegistry.salesprojectState = function(){return "SalesprojectState";};
-$KeywordRegistry.salesprojectState$open = function(){return "SALPROJSTATOPEN                     ";};
-$KeywordRegistry.salesprojectState$postponed = function(){return "SALPROJSTATPOSTPONED                ";};
-$KeywordRegistry.salesprojectState$aborted = function(){return "SALPROJSTATABORT                    ";};
-$KeywordRegistry.salesprojectState$partialOrder = function(){return "SALPROJSTATPARTIAL                  ";};
-$KeywordRegistry.salesprojectState$order = function(){return "SALPROJSTATORDER                    ";};
-$KeywordRegistry.salesprojectState$lost = function(){return "SALPROJSTATLOST                     ";};
+$KeywordRegistry.salesprojectState$open = function(){return $KeywordRegistry._autoPad("SALPROJSTATOPEN");};
+$KeywordRegistry.salesprojectState$postponed = function(){return $KeywordRegistry._autoPad("SALPROJSTATPOSTPONED");};
+$KeywordRegistry.salesprojectState$aborted = function(){return $KeywordRegistry._autoPad("SALPROJSTATABORT");};
+$KeywordRegistry.salesprojectState$partialOrder = function(){return $KeywordRegistry._autoPad("SALPROJSTATPARTIAL");};
+$KeywordRegistry.salesprojectState$order = function(){return $KeywordRegistry._autoPad("SALPROJSTATORDER");};
+$KeywordRegistry.salesprojectState$lost = function(){return $KeywordRegistry._autoPad("SALPROJSTATLOST");};
 
 $KeywordRegistry.salesprojectPhase = function(){return "SalesprojectPhase";};
-$KeywordRegistry.salesprojectPhase$nqc = function(){return "SALPROJPHASENQC                     ";};
+$KeywordRegistry.salesprojectPhase$nqc = function(){return $KeywordRegistry._autoPad("SALPROJPHASENQC");};
 
 $KeywordRegistry.taskPriority = function(){return "TaskPriority";};
-$KeywordRegistry.taskPriority$none = function(){return "TASKPRIONONE                        ";};
-$KeywordRegistry.taskPriority$low = function(){return "TASKPRIOLOW                         ";};
-$KeywordRegistry.taskPriority$medium = function(){return "TASKPRIOMEDIUM                      ";};
-$KeywordRegistry.taskPriority$high = function(){return "TASKPRIOHIGH                        ";};
+$KeywordRegistry.taskPriority$none = function(){return $KeywordRegistry._autoPad("TASKPRIONONE");};
+$KeywordRegistry.taskPriority$low = function(){return $KeywordRegistry._autoPad("TASKPRIOLOW");};
+$KeywordRegistry.taskPriority$medium = function(){return $KeywordRegistry._autoPad("TASKPRIOMEDIUM");};
+$KeywordRegistry.taskPriority$high = function(){return $KeywordRegistry._autoPad("TASKPRIOHIGH");};
 
 $KeywordRegistry.taskProgress = function(){return "TaskProgress";};
-$KeywordRegistry.taskProgress$0 = function(){return "TASKPROG0                           ";};
+$KeywordRegistry.taskProgress$0 = function(){return $KeywordRegistry._autoPad("TASKPROG0");};
 
 $KeywordRegistry.competitionState = function(){return "CompetitionState";};
 $KeywordRegistry.objectRelationType = function(){return "ObjectRelationType";};
@@ -125,28 +126,28 @@ $KeywordRegistry.contactPosition = function(){return "ContactPosition";};
 $KeywordRegistry.contactContactrole = function(){return "ContactContactrole";};
 
 $KeywordRegistry.campaignState = function(){return "CampaignManagementStates";};
-$KeywordRegistry.campaignState$planning = function(){return "PLANNING                            ";};
-$KeywordRegistry.campaignState$approved = function(){return "APPROVED                            ";};
+$KeywordRegistry.campaignState$planning = function(){return $KeywordRegistry._autoPad("PLANNING");};
+$KeywordRegistry.campaignState$approved = function(){return $KeywordRegistry._autoPad("APPROVED");};
 
 $KeywordRegistry.campaignStepState = function(){return "CampaignManagementStepStates";};
-$KeywordRegistry.campaignStepState$open = function(){return "OPEN                                ";};
+$KeywordRegistry.campaignStepState$open = function(){return $KeywordRegistry._autoPad("OPEN");};
 
 $KeywordRegistry.campaignStepCostCategory = function(){return "CampaignManagementCostCategory";};
 
 $KeywordRegistry.documentTemplateType = function(){return "DocumentTemplateType";};
-$KeywordRegistry.documentTemplateType$letter = function(){return "LET                                 ";};
-$KeywordRegistry.documentTemplateType$mail = function(){return "MAI                                 ";};
-$KeywordRegistry.documentTemplateType$attachment = function(){return "ATT                                 ";};
+$KeywordRegistry.documentTemplateType$letter = function(){return $KeywordRegistry._autoPad("LET");};
+$KeywordRegistry.documentTemplateType$mail = function(){return $KeywordRegistry._autoPad("MAI");};
+$KeywordRegistry.documentTemplateType$attachment = function(){return $KeywordRegistry._autoPad("ATT");};
 
 $KeywordRegistry.documentTemplateTypeCategory = function(){return "DocumentTemplateTypeCategory";};
-$KeywordRegistry.documentTemplateTypeCategory$single = function(){return "1                                   ";};
-$KeywordRegistry.documentTemplateTypeCategory$serial = function(){return "2                                   ";};
+$KeywordRegistry.documentTemplateTypeCategory$single = function(){return $KeywordRegistry._autoPad("1");};
+$KeywordRegistry.documentTemplateTypeCategory$serial = function(){return $KeywordRegistry._autoPad("2");};
 
 $KeywordRegistry.classificationType = function(){return "ClassificationType";};
-$KeywordRegistry.classificationType$salesproject = function(){return "SALESPROJ";};
+$KeywordRegistry.classificationType$salesproject = function(){return $KeywordRegistry._autoPad("SALESPROJ");};
 
 $KeywordRegistry.personGender = function(){return "PersonGender";};
-$KeywordRegistry.personGender$other = function(){return "o";};
+$KeywordRegistry.personGender$other = function(){return $KeywordRegistry._autoPad("o");};
 
 $KeywordRegistry.permissionCondType = function(){return "PermissionCondType";};
 $KeywordRegistry.permissionAccessType = function(){return "PermissionAccessType";};
@@ -154,34 +155,34 @@ $KeywordRegistry.dsgvoPurpose = function(){return "DSGVOPurpose";};
 $KeywordRegistry.dsgvoStatuoritysource = function(){return "DSGVOStatuoritysource";};
 
 $KeywordRegistry.dsgvoType = function() {return "DSGVOType";};
-$KeywordRegistry.dsgvoType$birth = function() {return "TYPE_BIRTH                          ";};
+$KeywordRegistry.dsgvoType$birth = function(){return $KeywordRegistry._autoPad("TYPE_BIRTH");};
 
 $KeywordRegistry.dsgvoTransmission = function() {return "DSGVOTransmission";};
-$KeywordRegistry.dsgvoTransmission$none = function() {return   "DSGVONONE                           ";};
-$KeywordRegistry.dsgvoTransmission$inland = function() {return "DSGVOINLAND                         ";};
-$KeywordRegistry.dsgvoTransmission$foreign = function() {return "DSGVOFOREIGN                        ";};
+$KeywordRegistry.dsgvoTransmission$none = function(){return $KeywordRegistry._autoPad("DSGVONONE");};
+$KeywordRegistry.dsgvoTransmission$inland = function(){return $KeywordRegistry._autoPad("DSGVOINLAND");};
+$KeywordRegistry.dsgvoTransmission$foreign = function(){return $KeywordRegistry._autoPad("DSGVOFOREIGN");};
 
 $KeywordRegistry.dsgvoDeadline = function() {return "DSGVODeadline";};
-$KeywordRegistry.dsgvoDeadline$onTime = function() {return "DSGVOONTIME                         ";};
-$KeywordRegistry.dsgvoDeadline$complex = function() {return "DSGVODEADLINECOMPLEX                ";};
-$KeywordRegistry.dsgvoDeadline$count = function() {return "DSGVODEADLINECOUNT                  ";};
+$KeywordRegistry.dsgvoDeadline$onTime = function(){return $KeywordRegistry._autoPad("DSGVOONTIME");};
+$KeywordRegistry.dsgvoDeadline$complex = function(){return $KeywordRegistry._autoPad("DSGVODEADLINECOMPLEX");};
+$KeywordRegistry.dsgvoDeadline$count = function(){return $KeywordRegistry._autoPad("DSGVODEADLINECOUNT");};
 $KeywordRegistry.dsgvoGuarantee = function() {return "DSGVOGuarantee";};
 
 $KeywordRegistry.textPlaceholder = function(){return "textPlaceholder";};
 
 $KeywordRegistry.communicationMediumCampaign = function(){return "CommunicationMediumCampaign";};
-$KeywordRegistry.communicationMediumCampaign$mail = function(){return "CAMPAIGNEMAIL                       ";};
-$KeywordRegistry.communicationMediumCampaign$letter = function(){return "CAMPAIGNLETTER                      ";};
+$KeywordRegistry.communicationMediumCampaign$mail = function(){return $KeywordRegistry._autoPad("CAMPAIGNEMAIL");};
+$KeywordRegistry.communicationMediumCampaign$letter = function(){return $KeywordRegistry._autoPad("CAMPAIGNLETTER");};
 
 $KeywordRegistry.bulkMailRecipientStatus = function(){return "BulkMailRecipientStatus";};
-$KeywordRegistry.bulkMailRecipientStatus$pending = function(){return "EMAILPENDING                        ";};
-$KeywordRegistry.bulkMailRecipientStatus$sent = function(){return "EMAILSENT                           ";};
-$KeywordRegistry.bulkMailRecipientStatus$failed = function(){return "EMAILFAILED                         ";};
+$KeywordRegistry.bulkMailRecipientStatus$pending = function(){return $KeywordRegistry._autoPad("EMAILPENDING");};
+$KeywordRegistry.bulkMailRecipientStatus$sent = function(){return $KeywordRegistry._autoPad("EMAILSENT");};
+$KeywordRegistry.bulkMailRecipientStatus$failed = function(){return $KeywordRegistry._autoPad("EMAILFAILED");};
 
 $KeywordRegistry.bulkMailStatus = function(){return "BulkMailStatus";};
-$KeywordRegistry.bulkMailStatus$notSent = function(){return "BULKMAILNOTSENT                     ";};
-$KeywordRegistry.bulkMailStatus$beingSent = function(){return "BULKMAILBEINGSENT                   ";};
-$KeywordRegistry.bulkMailStatus$sent = function(){return "BULKMAILSENT                        ";};
+$KeywordRegistry.bulkMailStatus$notSent = function(){return $KeywordRegistry._autoPad("BULKMAILNOTSENT");};
+$KeywordRegistry.bulkMailStatus$beingSent = function(){return $KeywordRegistry._autoPad("BULKMAILBEINGSENT");};
+$KeywordRegistry.bulkMailStatus$sent = function(){return $KeywordRegistry._autoPad("BULKMAILSENT");};
 
 $KeywordRegistry.callDirection = function(){return "CallDirection";};
 $KeywordRegistry.callDirection$incoming = function(){return $KeywordRegistry._autoPad("INC");};
diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js
index bc8e3cdaff76696243e3ef8095277694f70b33c8..97349505c724ec2fa47c9315e6a33f7c6078fb1b 100644
--- a/process/Sql_lib/process.js
+++ b/process/Sql_lib/process.js
@@ -317,13 +317,6 @@ SqlCondition.prototype.andPrepareVars = function(field, variable, cond, fieldTyp
     return this;
 }
 
-SqlCondition.prototype.andPrepareValue = function(field, value) {
-    if (value) {
-        return this.andPrepare(field, value, null, null);
-    }
-    return this;
-}
-
 /**
  * same as the "orPrepare"-function but with validation of adito-variables functionality
  * @param {String | String[]} field the database field as "tablename.columnname"; e.g. "ORGANISATION.NAME" or as array with column-alias: ["ORGANISATION", "NAME", "myorgAlias"]
@@ -842,25 +835,20 @@ SqlBuilder.prototype.having = function (pCondition)
 SqlBuilder.prototype._getClause = function (pElement, pPrefix, pAutoJoin)
 {
     var preparedValues = [];
-    if (pElement instanceof SqlBuilder || pElement instanceof SqlCondition)
-    {
-        pElement = _getElement(pElement);
-    }
-    else if (typeof pElement !== "string" && pElement.length !== undefined) //array
+    if (typeof pElement !== "string")
     {
-        if (pAutoJoin)
+        if (pElement.length !== undefined && pAutoJoin) //array of fields
         {
             for (let i = 0, l = pElement.length; i < l; i++)
             {
-                if (pElement[i] instanceof SqlBuilder)
-                    pElement[i] = _getElement(pElement);
+                if (typeof pElement[i] !== "string")
+                    pElement[i] = _getElement(pElement[i]);
             }
             pElement = pElement.join(", ");
         }
         else
         {
-            preparedValues = preparedValues.concat(pElement[1]);
-            pElement = pElement[0];
+            pElement = _getElement(pElement);
         }
     }
     
@@ -871,9 +859,10 @@ SqlBuilder.prototype._getClause = function (pElement, pPrefix, pAutoJoin)
     
     function _getElement (element)
     {
-        element = element.build();
+        if (element instanceof SqlBuilder || element instanceof SqlCondition)
+            element = element.build();
         preparedValues = preparedValues.concat(element[1]);
-        if (element instanceof SqlBuilder)
+        if (element instanceof SqlBuilder || pAutoJoin)
             return "(" + element[0] + ")";
         return element[0];
     }
diff --git a/process/Ticket_lib/process.js b/process/Ticket_lib/process.js
index 33462056aca919ed342ba0490604ecacb1d2ec7f..c3bf8bde8a6ec5c6cb80386591b120769e51a150 100644
--- a/process/Ticket_lib/process.js
+++ b/process/Ticket_lib/process.js
@@ -55,8 +55,7 @@ TicketUtils.getStatusIcon = function(pStatus)
  */
 TicketUtils.addLinkRecords= function(pObjectIdField, pRowIdField, pAdditionalLinksField, pParentContextField, pParentIdField)
 {
-    throw Error("Not implemented yet");
-    //TaskUtils.addLinkRecords(pObjectIdField, pRowIdField, pAdditionalLinksField, pParentContextField, pParentIdField, "Links");
+    TaskUtils.addLinkRecords(pObjectIdField, pRowIdField, pAdditionalLinksField, pParentContextField, pParentIdField, "Links");
 }
    
 /**
@@ -123,7 +122,7 @@ TicketUtils.prototype.getAvailableStatus = function()
     if (states == null)
         return states;
     
-    return states.map(StringUtils.toChar36);
+    return states.map(StringUtils.pad36);
 }
 
 /**
@@ -133,7 +132,7 @@ TicketUtils.prototype.getAvailableStatus = function()
  */
 TicketUtils.prototype.getDefaultStatus = function()
 {
-    return StringUtils.toChar36(KeywordUtils.getAttributeRelation(this.type, $KeywordRegistry.ticketType(), "defaultStatus", ""));
+    return StringUtils.pad36(KeywordUtils.getAttributeRelation(this.type, $KeywordRegistry.ticketType(), "defaultStatus", ""));
 }
 
 /**
diff --git a/process/Util_lib/process.js b/process/Util_lib/process.js
index 75e04839b348358a042d57788a757b7de53c9107..de5d265459ddeb922c5c7dc07c679a00daaa4c77 100644
--- a/process/Util_lib/process.js
+++ b/process/Util_lib/process.js
@@ -43,7 +43,7 @@ StringUtils.concat = function(pSeparator, pElements)
 /**
  * converts a string to a string of always 36 chars. Whitespaces are added at the end if needed.
  */
-StringUtils.toChar36 = function(pValue) 
+StringUtils.pad36 = function(pValue) 
 {
     return (pValue + "                                    ").slice(0, 36);
 }
diff --git a/report/Offer_report/ribbon/ribbontasks/task_report/customcomponents/button/onClick.js b/report/Offer_report/ribbon/ribbontasks/task_report/customcomponents/button/onClick.js
index 475d8abf9eb731b6a8830bb7e81bab59abc81fb9..21f2f76bca0a17c2dfcc3d266126dde3fe412560 100644
--- a/report/Offer_report/ribbon/ribbontasks/task_report/customcomponents/button/onClick.js
+++ b/report/Offer_report/ribbon/ribbontasks/task_report/customcomponents/button/onClick.js
@@ -4,7 +4,6 @@ import("system.translate");
 import("system.question");
 import("system.vars");
 import("system.db");
-import("lib_email");
 
 var details = vars.get("$global.RptOfferOrderDetails");
 var orgid = db.cell("select ORGANISATION_ID from CONTACT where CONTACTID = '" + details[1] + "'");