diff --git a/aliasDefinition/Data_alias/Data_alias.aod b/aliasDefinition/Data_alias/Data_alias.aod
index 0673fab6659afbf5bfe6e886f9b9de938cdb928f..de3b537eb9c335c04569c56e16867be3faa4b694 100644
--- a/aliasDefinition/Data_alias/Data_alias.aod
+++ b/aliasDefinition/Data_alias/Data_alias.aod
@@ -15791,7 +15791,7 @@
             <description></description>
             <auditSyncConfig>
               <name>auditSyncConfig</name>
-              <auditMode v="0" />
+              <auditMode v="1" />
               <syncActive v="false" />
               <syncComplete v="true" />
               <syncDirection v="1" />
@@ -15823,8 +15823,20 @@
                 <isUnique v="false" />
                 <index v="false" />
                 <documentation></documentation>
-                <title></title>
+                <title>District assignment status</title>
                 <description></description>
+                <customProperties>
+                  <customBooleanProperty>
+                    <name>log</name>
+                    <global v="false" />
+                    <property v="true" />
+                  </customBooleanProperty>
+                  <customJDitoProperty>
+                    <name>translate4Log</name>
+                    <global v="false" />
+                    <property>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/districtcontact/entityfields/status/customproperties/translate4log/property.js</property>
+                  </customJDitoProperty>
+                </customProperties>
               </entityFieldDb>
               <entityFieldDb>
                 <name>ADVISER_ROLE</name>
@@ -15895,6 +15907,18 @@
                 <documentation></documentation>
                 <title></title>
                 <description></description>
+                <customProperties>
+                  <customBooleanProperty>
+                    <name>log</name>
+                    <global v="false" />
+                    <property v="false" />
+                  </customBooleanProperty>
+                  <customStringProperty>
+                    <name>tableRef</name>
+                    <global v="false" />
+                    <property>CONTACT</property>
+                  </customStringProperty>
+                </customProperties>
               </entityFieldDb>
               <entityFieldDb>
                 <name>VALID_FROM</name>
diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/districtcontact/entityfields/status/customproperties/translate4log/property.js b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/districtcontact/entityfields/status/customproperties/translate4log/property.js
new file mode 100644
index 0000000000000000000000000000000000000000..c079c7fd8009ca6915d731ed02160ad0e9d8ecfa
--- /dev/null
+++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/districtcontact/entityfields/status/customproperties/translate4log/property.js
@@ -0,0 +1,19 @@
+import("system.translate");
+import("Keyword_lib");
+import("KeywordRegistry_basic");
+import("District_lib");
+import("system.result");
+import("Loghistory_lib");
+import("Contact_lib");
+
+var params = Translate4LogParams.load();
+
+//Keyword umschlüsseln
+var keyname = KeywordUtils.getViewValue($KeywordRegistry.contactStatus(), params.value);
+
+//Gebiet und Betreur umschlüsseln
+var arrDistrictContact = DistrictUtils.getDataFromDistrictContact(params.rowId);
+var districtName = DistrictUtils.getDistrictName(arrDistrictContact[0]);
+var adviserName = ContactUtils.getFullTitleByContactId(arrDistrictContact[1])
+
+result.string(keyname + " (" + translate.text("District") + ": " + districtName + "; " + translate.text("Adviser") + ": " + adviserName + ")");
\ No newline at end of file
diff --git a/entity/District_entity/District_entity.aod b/entity/District_entity/District_entity.aod
index 659e44b7f874f1d637273ff55d506a446d860841..fa41a81526f5375212d0744b02a25651701dee16 100644
--- a/entity/District_entity/District_entity.aod
+++ b/entity/District_entity/District_entity.aod
@@ -258,6 +258,11 @@
       <dropDownProcess>%aditoprj%/entity/District_entity/entityfields/district_autoadd/dropDownProcess.js</dropDownProcess>
       <valueProcess>%aditoprj%/entity/District_entity/entityfields/district_autoadd/valueProcess.js</valueProcess>
     </entityField>
+    <entityActionField>
+      <name>assignDistrict</name>
+      <title>Assign district</title>
+      <onActionProcess>%aditoprj%/entity/District_entity/entityfields/assigndistrict/onActionProcess.js</onActionProcess>
+    </entityActionField>
   </entityFields>
   <recordContainers>
     <dbRecordContainer>
diff --git a/entity/District_entity/entityfields/assigndistrict/onActionProcess.js b/entity/District_entity/entityfields/assigndistrict/onActionProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..301a4faa165f45602f002d29390ecc7d2a11ec6a
--- /dev/null
+++ b/entity/District_entity/entityfields/assigndistrict/onActionProcess.js
@@ -0,0 +1,13 @@
+import("system.question");
+import("system.util");
+import("system.notification");
+import("system.translate");
+import("District_lib");
+import("system.vars");
+
+var districtId = vars.get("$field.DISTRICTID");
+var appliedFilter = vars.get("$field.appliedFilter");
+
+question.showMessage(translate.text("District assignment will start now!"))
+
+DistrictUtils.assignDistrictOnServer(districtId, appliedFilter);
diff --git a/neonNotificationType/DistrictAssigned/DistrictAssigned.aod b/neonNotificationType/DistrictAssigned/DistrictAssigned.aod
new file mode 100644
index 0000000000000000000000000000000000000000..d3acf304d7d808619faba61d320706818107cb06
--- /dev/null
+++ b/neonNotificationType/DistrictAssigned/DistrictAssigned.aod
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonNotificationType xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonNotificationType/1.1.0">
+  <name>DistrictAssigned</name>
+  <title>District assigned</title>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <icon>VAADIN:GLOBE</icon>
+</neonNotificationType>
diff --git a/others/language_DE.txt b/others/language_DE.txt
index 08910a399410e73a226c2703be4c1e89f45a345b..7d3a7923a6bf19f212e11be043b80193707f9d8f 100644
--- a/others/language_DE.txt
+++ b/others/language_DE.txt
@@ -37,4 +37,24 @@
     <entry>
       <key>Field Service</key>
       <value>Außendienst</value>
+    </entry>
+    <entry>
+      <key>Assign district</key>
+      <value>Gebiet zuordnen</value>
+    </entry>
+    <entry>
+      <key>District assignment will start now!</key>
+      <value>Die Gebietszuordnung wird jetzt gestartet!</value>
+    </entry>
+    <entry>
+      <key>Assignment of district \"%0\" is completed!</key>
+      <value>Zuordnung des Gebietes \"%0\" ist abgeschlossen!</value>
+    </entry>
+    <entry>
+      <key>%0 companies were newley assigned to this district. \n %1 companies are no longer assigned to this district (these assignments got the status 'review'). \n %2 valid assignments were unchanged. \n The Process took %3 seconds. </key>
+      <value>%0 Firmen wurden dem Gebiet neu hinzugefügt. \n %1 Firmen sind diesem Gebiet nicht länger zugeordnet (diese Zuordnungen wurden auf den Status 'zur Prüfung' gesetzt). \n %2 gültige Zuordnungen blieben unverändert. \n Der Prozess dauert %3 Sekunden. </value>
+    </entry>
+    <entry>
+      <key>District assignment status</key>
+      <value>Gebietzuordnungstatus</value>
     </entry>
\ No newline at end of file
diff --git a/others/language_EN.txt b/others/language_EN.txt
index 651df12fdc8a3d948cb68b68178f5c4a1f871d59..7a6da3e4bef09597d2498d577104d3d2b89bf315 100644
--- a/others/language_EN.txt
+++ b/others/language_EN.txt
@@ -27,4 +27,19 @@
     </entry>
     <entry>
       <key>Field Service</key>
+    </entry>
+    <entry>
+      <key>Assign district</key>
+    </entry>
+    <entry>
+      <key>District assignment will start now!</key>
+    </entry>
+    <entry>
+      <key>Assignment of district \"%0\" is completed!</key>
+    </entry>
+    <entry>
+      <key>%0 companies were newley assigned to this district. \n %1 companies are no longer assigned to this district (these assignments got the status 'review'). \n %2 valid assignments were unchanged. \n The Process took %3 seconds. </key>
+    </entry>
+    <entry>
+      <key>District assignment status</key>
     </entry>
\ No newline at end of file
diff --git a/process/District_lib/District_lib.aod b/process/District_lib/District_lib.aod
new file mode 100644
index 0000000000000000000000000000000000000000..e349479bbe39378afa83ce81559bda59e9ad12d6
--- /dev/null
+++ b/process/District_lib/District_lib.aod
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1">
+  <name>District_lib</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <process>%aditoprj%/process/District_lib/process.js</process>
+  <alias>Data_alias</alias>
+  <variants>
+    <element>LIBRARY</element>
+  </variants>
+</process>
diff --git a/process/District_lib/process.js b/process/District_lib/process.js
new file mode 100644
index 0000000000000000000000000000000000000000..03abf8d35d1f5bee408a4c4cff09182fbcad1a67
--- /dev/null
+++ b/process/District_lib/process.js
@@ -0,0 +1,219 @@
+import("KeywordRegistry_basic");
+import("system.vars");
+import("system.util");
+import("Sql_lib");
+import("Util_lib");
+import("system.db");
+import("system.indexsearch");
+import("JditoFilter_lib");
+import("Util_lib");
+import("system.process");
+import("Employee_lib");
+
+/**
+ * Functions for district.
+ */
+function DistrictUtils () {}
+
+/**
+ * Gets the name of a district
+ * 
+ * @param {String} pDistrictId                  <p>
+ *                                              Id of the district.<br>
+ * @return {String}                             <p>
+ *                                              Name of the district.<br>
+ */
+DistrictUtils.getDistrictName = function (pDistrictId)
+{
+    var districtName = newSelect("DISTRICT_NAME")
+                            .from("DISTRICT")
+                            .where("DISTRICT.DISTRICTID", pDistrictId)
+                            .cell(true);    
+                            
+    return(districtName)
+}
+
+/**
+ * Gets the id of a district
+ * 
+ * @param {String} pDistrictContactId           <p>
+ *                                              Id of the districtcontact.<br>
+ * @return {Array}                              <p>
+ *                                              array of data from one districtcontact dataset <br>
+ */
+DistrictUtils.getDataFromDistrictContact = function (pDistrictContactId)
+{
+    var arrData = newSelect("DISTRICT_ID, ADVISER_CONTACT_ID")
+                            .from("DISTRICTCONTACT")
+                            .where("DISTRICTCONTACT.DISTRICTCONTACTID", pDistrictContactId)
+                            .arrayRow();    
+                            
+    return(arrData);
+}
+
+
+/**
+ * Executes a process to assign districts on the server and creates a notification when finished.
+ * 
+ * @param {String} pDistrictId                      <p>
+ *                                                  Id of the district.<br>
+ * @param {String} pAppliedFilter                   <p>
+ *                                                  Filter condition to get the assigned companies.<br>
+ * @param {String} pUser=currentUser (optional)     <p>
+ *                                                  User that will get the notification, <br>
+ *                                                  if null (not undefined!), no notification<br>
+ *                                                  will be created.<br>
+ */
+DistrictUtils.assignDistrictOnServer = function (pDistrictId, pAppliedFilter, pUser)
+{
+    //pUser hat folgendes Format: _____USER_bcdfb521-c7d0-4ef1-8916-78e7d3232046
+    if (pUser === undefined)
+        pUser = EmployeeUtils.getCurrentUserId();
+    var processConfig = process.createStartAsyncConfig()
+        .setName("assignDistrict_serverProcess")
+        .setLocalVariables({
+            districtId : pDistrictId,
+            appliedFilter : pAppliedFilter,
+            user : pUser || ""
+        })
+        .setUser(pUser)
+    process.startAsync(processConfig);
+}
+
+/**
+ * Assignes a district to companies. You should only call this function on the server because it
+ * can take some time to execute, use DistrictUtils.assignDistrictOnServer instead.
+ * 
+ * @param {String} pDistrictId                  <p>
+ *                                              Id of the district.<br>
+ * @param {String} pAppliedFilter               <p>
+ *                                              Filter condition to get the assigned companies.<br>
+ * @return {Object}                             <p>
+ *                                              Count of new assigned companies and no longer assigned companies.<br>
+ */
+DistrictUtils.assignDistrict = function (pDistrictId, pAppliedFilter)
+{    
+    var newAssigned = 0;
+    var unchanged = 0;
+    var invalid = 0;
+    
+    //Einlesen von allen bereits existierenden automatischen Zuordnungen,
+    //die nicht auf Status 'zur Prüfung' sthen
+    var arrExistingIds = new SqlBuilder()
+            .select("DISTRICTCONTACT.DISTRICTCONTACTID, DISTRICTCONTACT.CONTACT_ID, DISTRICTCONTACT.ADVISER_CONTACT_ID")
+            .from("DISTRICTCONTACT")    
+            .where("DISTRICTCONTACT.DISTRICT_ID", pDistrictId)
+            .and ("DISTRICTCONTACT.ORIGIN", $KeywordRegistry.districtOrigin$auto())
+            .and ("DISTRICTCONTACT.STATUS", $KeywordRegistry.contactStatus$inReview(), SqlBuilder.NOT_EQUAL())
+            .table();    
+
+    //Einlesen aller Betreuer, die dem übergebenen Gebiet zugeordnet sind
+    var arrResponsibleIds = new SqlBuilder()
+            .select("DISTRICTRESPONSIBLE.EMPLOYEE_CONTACT_ID, DISTRICTRESPONSIBLE.ADVISER_ROLE, " +
+                    "DISTRICTRESPONSIBLE.ADVISER_STATUS, DISTRICTRESPONSIBLE.VALID_FROM, DISTRICTRESPONSIBLE.VALID_UNTIL")
+            .from("DISTRICTRESPONSIBLE")    
+            .where("DISTRICTRESPONSIBLE.DISTRICT_ID", pDistrictId)
+            .table();
+        
+    //Aufbereiten des im JSON-Format übergebenen Filters in eine SQL-Condition
+    var appliedFilterCondition = JSON.parse(pAppliedFilter).filter;
+    appliedFilterCondition = JSON.stringify(appliedFilterCondition);        
+    var sqlCondition = db.toFilterCondition(appliedFilterCondition, "Organisation_entity")    
+    
+    //Einlesen der Contact-IDs zu den Firmen, die gemäß Filter diesem Gebiet zugeordnet sind
+    var arrOrgContactIds = new SqlBuilder()
+            .selectDistinct("CONTACT.CONTACTID")
+            .from("ORGANISATION")
+            .join("CONTACT", newWhere("ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID").and("CONTACT.PERSON_ID is null"))
+            .leftJoin("ADDRESS", "ADDRESS.ADDRESSID = CONTACT.ADDRESS_ID")
+            .leftJoin("CLASSIFICATIONSTORAGE", "CLASSIFICATIONSTORAGE.OBJECT_ROWID = CONTACT.CONTACTID")
+            .whereIfSet(sqlCondition)
+            .arrayColumn();   
+    
+    var insertArray = [];
+    var colsInsert = [
+            "DISTRICTCONTACTID",
+            "CONTACT_ID",
+            "DISTRICT_ID",
+            "ADVISER_CONTACT_ID",
+            "ADVISER_ROLE",
+            "STATUS",
+            "VALID_FROM", 
+            "VALID_UNTIL",
+            "ORIGIN"/*,
+            "USER_NEW",
+            "DATE_NEW"*/
+        ];
+    var updateArray = [];
+    var colsUpdate = [
+            "STATUS"/*,
+            "USER_EDIT",
+            "DATE_EDIT"*/
+        ];        
+
+    //Anlegen der Firmen-Betreuer-Datensätze in der Tabelle DISTRICTCONTACT
+    for (var i=0; i<arrOrgContactIds.length; i++)
+    {
+        for (var j=0; j<arrResponsibleIds.length; j++)
+        {
+            //Existiert der Firmen-Betreuer-Datensatz bereits?
+            var found = 'N'
+            for (var k=0; k<arrExistingIds.length; k++)
+            {
+                if (arrExistingIds[k][1] == arrOrgContactIds[i] && arrExistingIds[k][2] == arrResponsibleIds[j][0])
+                {
+                    unchanged++;
+                    found = 'Y';
+                    //Gefundenen Eintrag aus dem Array entfernen 
+                    //-> Am Schluss bleiben in dem Array alle ungültigen Datensätze übrig. Bei diesen wird weiter unten der Status geändert 
+                    arrExistingIds.splice(k, 1);
+                    break;
+                }
+            }
+            //Firmen-Betreuer-Datensatz existiert noch nicht -> Insert
+            if (found == 'N')
+            {
+                var valsInsert = [
+                    util.getNewUUID(),
+                    arrOrgContactIds[i],
+                    pDistrictId,
+                    arrResponsibleIds[j][0],
+                    arrResponsibleIds[j][1],
+                    arrResponsibleIds[j][2],
+                    arrResponsibleIds[j][3],
+                    arrResponsibleIds[j][4],
+                    $KeywordRegistry.districtOrigin$auto()/*,
+                    vars.get("$sys.user"),
+                    vars.get("$sys.date")*/
+                ];                
+                insertArray.push(["DISTRICTCONTACT", colsInsert, null, valsInsert]);
+            }            
+        }        
+    }
+    newAssigned = insertArray.length;
+    db.inserts(insertArray);    
+    
+    //Gibt es noch ungültige Zuordnungen, dann bei diesen den Status auf "zur Prüfung setzen"
+    if (arrExistingIds.length > 0)
+    {
+        invalid = arrExistingIds.length;
+        for (var l=0; l<arrExistingIds.length; l++)
+        {
+            var valsUpdate = [
+                $KeywordRegistry.contactStatus$inReview()/*,
+                vars.get("$sys.user"),
+                vars.get("$sys.date")*/
+            ];            
+            var condition = newWhere("DISTRICTCONTACT.DISTRICTCONTACTID", arrExistingIds[l][0]);
+            updateArray.push(["DISTRICTCONTACT", colsUpdate, null, valsUpdate, condition.build()]);
+        }
+        db.updates(updateArray)
+    }
+    
+    
+    return {
+        newAssigned : newAssigned,
+        invalid : invalid,
+        unchanged : unchanged
+    };    
+}
diff --git a/process/KeywordRegistry_basic/process.js b/process/KeywordRegistry_basic/process.js
index ba80197cd05d9f6c4c66c1c0a95cf557e578fe54..862d3cd9436eb371388fd8befec6406e22b8d280 100644
--- a/process/KeywordRegistry_basic/process.js
+++ b/process/KeywordRegistry_basic/process.js
@@ -41,6 +41,7 @@ $KeywordRegistry.activityDirection$internal = function(){return "x";};
 $KeywordRegistry.contactStatus = function(){return "ContactStatus";};
 $KeywordRegistry.contactStatus$active = function(){return "CONTACTSTATACTIVE";};
 $KeywordRegistry.contactStatus$inactive = function(){return "CONTACTSTATINACTIVE";};
+$KeywordRegistry.contactStatus$inReview = function(){return "CONTACTSTATREVIEW";};
 
 $KeywordRegistry.currency = function(){return "Currency";};
 $KeywordRegistry.currency$eur = function(){return "EUR";};
diff --git a/process/assignDistrict_serverProcess/assignDistrict_serverProcess.aod b/process/assignDistrict_serverProcess/assignDistrict_serverProcess.aod
new file mode 100644
index 0000000000000000000000000000000000000000..27ebc6a30b9f8341d70305bbda3555fd2a9e4bc5
--- /dev/null
+++ b/process/assignDistrict_serverProcess/assignDistrict_serverProcess.aod
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.1">
+  <name>assignDistrict_serverProcess</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <process>%aditoprj%/process/assignDistrict_serverProcess/process.js</process>
+  <alias>Data_alias</alias>
+  <variants>
+    <element>EXECUTABLE</element>
+  </variants>
+</process>
diff --git a/process/assignDistrict_serverProcess/process.js b/process/assignDistrict_serverProcess/process.js
new file mode 100644
index 0000000000000000000000000000000000000000..56666d0afbbbf651f87e3a0ec267fbe4950ecad5
--- /dev/null
+++ b/process/assignDistrict_serverProcess/process.js
@@ -0,0 +1,27 @@
+import("system.logging");
+import("system.datetime");
+import("Sql_lib");
+import("system.db");
+import("system.util");
+import("system.translate");
+import("system.vars");
+import("system.notification");
+import("District_lib");
+
+var startTime = datetime.date();
+var appliedFilter = vars.get("$local.appliedFilter")
+var user = vars.get("$local.user");
+var districtId = vars.get("$local.districtId");
+var districtName = DistrictUtils.getDistrictName(districtId);
+
+//Automatische Zuordnung 
+var res = DistrictUtils.assignDistrict(districtId, appliedFilter);
+
+// Benachrichtigung am Ende der Zuordnung                        
+var message = translate.withArguments("Assignment of district \"%0\" is completed!", [districtName]);
+var description = translate.withArguments("%0 companies were newley assigned to this district. \n " +
+                  "%1 companies are no longer assigned to this district (these assignments got the status 'review'). \n " + 
+                  "%2 valid assignments were unchanged. \n " +
+                  "The Process took %3 seconds. ",
+                  [res.newAssigned, res.invalid, res.unchanged, Math.round((datetime.date() - startTime) / datetime.ONE_SECOND)])
+notification.addNotification(util.getNewUUID(), null, null, null, "DistrictAssigned", notification.PRIO_NORMAL, 2, notification.STATE_UNSEEN, [user], message, description);