diff --git a/.liquibase/Data_alias/basic/2021.1.3/changelog.xml b/.liquibase/Data_alias/basic/2021.1.3/changelog.xml
index 873ee73a18365693f428621f488b2483430f5dd7..64b38eb5edad2568d6ec761202a1fc57587489f1 100644
--- a/.liquibase/Data_alias/basic/2021.1.3/changelog.xml
+++ b/.liquibase/Data_alias/basic/2021.1.3/changelog.xml
@@ -8,4 +8,5 @@
     <include relativeToChangelogFile="true" file="alter_dataTypesToDateTime.xml"/>
     <include relativeToChangelogFile="true" file="Grouptask/changelog.xml"/>
     <include relativeToChangelogFile="true" file="Campaign/changelog.xml"/>
+    <include relativeToChangelogFile="true" file="Visitplan/changelog.xml"/>
 </databaseChangeLog>
\ No newline at end of file
diff --git a/entity/Appointment_entity/Appointment_entity.aod b/entity/Appointment_entity/Appointment_entity.aod
index 87ccae159e555fe7fe4c8be557f4cea197952512..72d4bc3f105a013b5776bc8bc79bf703fb499a89 100644
--- a/entity/Appointment_entity/Appointment_entity.aod
+++ b/entity/Appointment_entity/Appointment_entity.aod
@@ -208,6 +208,10 @@
           <valueProcess>%aditoprj%/entity/Appointment_entity/entityfields/appointmentlinks/children/appointmentstate_param/valueProcess.js</valueProcess>
           <expose v="false" />
         </entityParameter>
+        <entityParameter>
+          <name>AppointmentId_param</name>
+          <valueProcess>%aditoprj%/entity/Appointment_entity/entityfields/appointmentlinks/children/appointmentid_param/valueProcess.js</valueProcess>
+        </entityParameter>
       </children>
     </entityConsumer>
     <entityActionField>
@@ -268,6 +272,10 @@
       <valueProcess>%aditoprj%/entity/Appointment_entity/entityfields/erroronpermissiondenied/valueProcess.js</valueProcess>
       <expose v="true" />
     </entityParameter>
+    <entityParameter>
+      <name>Visitplanentry_param</name>
+      <expose v="true" />
+    </entityParameter>
     <entityParameter>
       <name>VisitPlanId_param</name>
       <expose v="true" />
diff --git a/entity/Appointment_entity/recordcontainers/jdito/onInsert.js b/entity/Appointment_entity/recordcontainers/jdito/onInsert.js
index f4dc0bbb6a1704ea933d2b4e6eafe75e004a2f0d..bf3287efddafc930688f1634353b11612a62035d 100644
--- a/entity/Appointment_entity/recordcontainers/jdito/onInsert.js
+++ b/entity/Appointment_entity/recordcontainers/jdito/onInsert.js
@@ -1,3 +1,4 @@
+import("KeywordRegistry_basic");
 import("Sql_lib");
 import("system.calendars");
 import("system.question");
@@ -43,9 +44,21 @@ if (fields["REMINDER.value"])
 event[calendars.ID] = calendars.insert([event])[0];
 neon.setFieldValue("$field.UID", event[calendars.ID]);
 
-vars.set("$context.editmode", calendars.MODE_UPDATE);
-
-if(vars.exists("$param.VisitPlanId_param") && vars.get("$param.VisitPlanId_param"))
+if(vars.get("$param.Visitplanentry_param"))
 {
-    newWhere("VISITPLANENTRY.VISITPLANENTRYID", vars.get("$param.VisitPlanId_param")).updateData(true, "VISITPLANENTRY", ["APPOINTMENT_ID"], null, [event[calendars.ID]]);
-}
\ No newline at end of file
+    var statusApp = $KeywordRegistry.visitPlanEntryStatusAppointment$requested();
+    var statusPlan = $KeywordRegistry.visitPlanEntryStatus$planned();
+
+    if(event[calendars.STATUS] == "CONFIRMED")
+    {
+        statusApp = $KeywordRegistry.visitPlanEntryStatusAppointment$confirmed();
+        statusPlan = $KeywordRegistry.visitPlanEntryStatus$Appointmentarranged();
+    }
+    
+    var columns = ["APPOINTMENT_ID", "STATUS_APPOINTMENT", "STATUS"];
+    var values = [event[calendars.ID], statusApp, statusPlan];
+    var updateEntry = newWhere("VISITPLANENTRY.VISITPLANENTRYID", vars.get("$param.Visitplanentry_param"))
+    .updateData(true, "VISITPLANENTRY", columns, null, values);
+}
+
+vars.set("$context.editmode", calendars.MODE_UPDATE);
diff --git a/entity/Appointment_entity/recordcontainers/jdito/onUpdate.js b/entity/Appointment_entity/recordcontainers/jdito/onUpdate.js
index dde683a8929aa922bdb8041662279a61d8e33a1b..6c5162502cac09ceca12e341d241ddec2d6c19e4 100644
--- a/entity/Appointment_entity/recordcontainers/jdito/onUpdate.js
+++ b/entity/Appointment_entity/recordcontainers/jdito/onUpdate.js
@@ -1,3 +1,5 @@
+import("KeywordRegistry_basic");
+import("Sql_lib");
 import("system.neon");
 import("system.calendars");
 import("system.vars");
@@ -66,6 +68,22 @@ if(event)
 }
 
 
+if(vars.get("$param.Visitplanentry_param"))
+{    
+    var statusApp = $KeywordRegistry.visitPlanEntryStatusAppointment$requested();
+    var statusPlan = $KeywordRegistry.visitPlanEntryStatus$planned();
+    
+    if(event[calendars.STATUS] == "CONFIRMED")
+    {
+        statusApp = $KeywordRegistry.visitPlanEntryStatusAppointment$confirmed();
+        statusPlan = $KeywordRegistry.visitPlanEntryStatus$Appointmentarranged();
+    }    
+            
+    var values = [statusPlan, statusApp];
+    var columns = ["STATUS", "STATUS_APPOINTMENT"];
+    var updateEntry = newWhere("VISITPLANENTRY.VISITPLANENTRYID", visitplanentry)
+    .updateData(true, "VISITPLANENTRY", columns, null, values);
+}
 
 /**
 * checks if the entryParam has different values like the current fieldvalues
diff --git a/entity/VisitPlanEntry_entity/VisitPlanEntry_entity.aod b/entity/VisitPlanEntry_entity/VisitPlanEntry_entity.aod
index eb8f3cd9ad4e6ec22ef76b8acad086106ddd74b3..aeb16ce13ea8ade3db6e1e00f5b0eb7995bf0a88 100644
--- a/entity/VisitPlanEntry_entity/VisitPlanEntry_entity.aod
+++ b/entity/VisitPlanEntry_entity/VisitPlanEntry_entity.aod
@@ -173,7 +173,11 @@
     <entityField>
       <name>APPOINTMENT_ID</name>
       <documentation>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/appointment_id/documentation.adoc</documentation>
+      <title>Appointment</title>
+      <consumer>Appointments</consumer>
       <linkedContext>Appointment</linkedContext>
+      <valueProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/appointment_id/valueProcess.js</valueProcess>
+      <displayValueProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/appointment_id/displayValueProcess.js</displayValueProcess>
     </entityField>
     <entityParameter>
       <name>VisitPlanEmployeeWeek_param</name>
@@ -362,17 +366,83 @@
         </entityParameter>
       </children>
     </entityConsumer>
-    <entityActionField>
-      <name>NewActivity</name>
-      <documentation>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/newactivity/documentation.adoc</documentation>
-      <title>Create Visitreport</title>
-      <onActionProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/newactivity/onActionProcess.js</onActionProcess>
-      <isMenuAction v="true" />
-      <iconId>VAADIN:HOURGLASS_END</iconId>
-      <stateProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/newactivity/stateProcess.js</stateProcess>
-      <tooltip>Create Visitreport</tooltip>
-      <tooltipProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/newactivity/tooltipProcess.js</tooltipProcess>
-    </entityActionField>
+    <entityConsumer>
+      <name>Appointments</name>
+      <isOneToOneRelationship v="true" />
+      <dependency>
+        <name>dependency</name>
+        <entityName>Appointment_entity</entityName>
+        <fieldName>LinkedAppointments</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>LinkedObjectId_param</name>
+          <valueProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/appointments/children/linkedobjectid_param/valueProcess.js</valueProcess>
+        </entityParameter>
+        <entityParameter>
+          <name>Visitplanentry_param</name>
+          <valueProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/appointments/children/visitplanentry_param/valueProcess.js</valueProcess>
+        </entityParameter>
+      </children>
+    </entityConsumer>
+    <entityField>
+      <name>APPOINTMENT_BEGIN_TIME</name>
+      <title>Appointment Start</title>
+      <contentType>DATE</contentType>
+      <outputFormat>dd.MM.yyyy HH:mm</outputFormat>
+      <valueProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/appointment_begin_time/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>APPOINTMENT_END_TIME</name>
+      <title>Appointment End</title>
+      <contentType>DATE</contentType>
+      <outputFormat>dd.MM.yyyy HH:mm</outputFormat>
+      <valueProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/appointment_end_time/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>APPOINTMENT_STATUS</name>
+      <title>Appointment Status</title>
+      <valueProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/appointment_status/valueProcess.js</valueProcess>
+      <displayValueProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/appointment_status/displayValueProcess.js</displayValueProcess>
+    </entityField>
+    <entityField>
+      <name>APPOINTMENT_SUBJECT</name>
+      <title>Appointment Subject</title>
+      <valueProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/appointment_subject/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>syncIcon</name>
+      <colorProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/syncicon/colorProcess.js</colorProcess>
+      <contentType>IMAGE</contentType>
+      <valueProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/syncicon/valueProcess.js</valueProcess>
+    </entityField>
+    <entityActionGroup>
+      <name>entityActionGroup</name>
+      <iconId>VAADIN:CALENDAR</iconId>
+      <children>
+        <entityActionField>
+          <name>NewActivity</name>
+          <documentation>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newactivity/documentation.adoc</documentation>
+          <title>Create Visitreport</title>
+          <onActionProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newactivity/onActionProcess.js</onActionProcess>
+          <isMenuAction v="true" />
+          <iconId>VAADIN:HOURGLASS_END</iconId>
+          <stateProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newactivity/stateProcess.js</stateProcess>
+          <tooltip>Create Visitreport</tooltip>
+          <tooltipProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newactivity/tooltipProcess.js</tooltipProcess>
+        </entityActionField>
+        <entityActionField>
+          <name>NewAppointment</name>
+          <documentation>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newappointment/documentation.adoc</documentation>
+          <title>New Appointment</title>
+          <onActionProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newappointment/onActionProcess.js</onActionProcess>
+          <iconId>VAADIN:CALENDAR</iconId>
+          <state>EDITABLE</state>
+          <tooltip>Create new Appointment</tooltip>
+          <tooltipProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newappointment/tooltipProcess.js</tooltipProcess>
+        </entityActionField>
+      </children>
+    </entityActionGroup>
     <entityActionField>
       <name>OpenRoute</name>
       <documentation>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/openroute/documentation.adoc</documentation>
@@ -382,33 +452,45 @@
       <iconId>VAADIN:MAP_MARKER</iconId>
       <stateProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/openroute/stateProcess.js</stateProcess>
     </entityActionField>
-    <entityActionField>
-      <name>NewAppointment</name>
-      <documentation>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/newappointment/documentation.adoc</documentation>
-      <title>New Appointment</title>
-      <onActionProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/newappointment/onActionProcess.js</onActionProcess>
-      <isMenuAction v="true" />
-      <iconId>VAADIN:CALENDAR</iconId>
+    <entityActionGroup>
+      <name>sync</name>
+      <title>synchronize</title>
+      <iconId>VAADIN:REFRESH</iconId>
       <state>EDITABLE</state>
-      <stateProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/newappointment/stateProcess.js</stateProcess>
-      <tooltip>Create new Appointment</tooltip>
-      <tooltipProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/newappointment/tooltipProcess.js</tooltipProcess>
-    </entityActionField>
+      <stateProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/sync/stateProcess.js</stateProcess>
+      <children>
+        <entityActionField>
+          <name>syncPlanToAppointment</name>
+          <title>synchronize Plan to Appointment</title>
+          <onActionProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/sync/children/syncplantoappointment/onActionProcess.js</onActionProcess>
+          <isObjectAction v="false" />
+          <selectionType>MULTI</selectionType>
+          <iconId>VAADIN:ARROW_CIRCLE_RIGHT</iconId>
+        </entityActionField>
+        <entityActionField>
+          <name>syncAppointmentToPlan</name>
+          <title>synchronize Appointment to Plan</title>
+          <onActionProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/sync/children/syncappointmenttoplan/onActionProcess.js</onActionProcess>
+          <isObjectAction v="false" />
+          <selectionType>MULTI</selectionType>
+          <iconId>VAADIN:ARROW_CIRCLE_LEFT</iconId>
+        </entityActionField>
+      </children>
+    </entityActionGroup>
     <entityActionGroup>
-      <name>entityActionGroup</name>
-      <iconId>VAADIN:CALENDAR</iconId>
+      <name>ActionGroupOpenDayRoute</name>
       <children>
         <entityActionField>
           <name>OpenDayRoute</name>
-          <documentation>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/documentation.adoc</documentation>
+          <documentation>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/documentation.adoc</documentation>
           <title>Open Route of the day</title>
-          <onActionProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/onActionProcess.js</onActionProcess>
+          <onActionProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/onActionProcess.js</onActionProcess>
           <isObjectAction v="false" />
           <selectionType>MULTI</selectionType>
           <iconId>VAADIN:MAP_MARKER</iconId>
-          <stateProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/stateProcess.js</stateProcess>
+          <stateProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/stateProcess.js</stateProcess>
           <tooltip>Open route</tooltip>
-          <tooltipProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/tooltipProcess.js</tooltipProcess>
+          <tooltipProcess>%aditoprj%/entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/tooltipProcess.js</tooltipProcess>
         </entityActionField>
       </children>
     </entityActionGroup>
diff --git a/entity/VisitPlanEntry_entity/afterSave.js b/entity/VisitPlanEntry_entity/afterSave.js
index efbd0a8d980a3b5182471dc011c26edf04156766..f81eeb6a459a1eb698a43880e41fa7176da6a211 100644
--- a/entity/VisitPlanEntry_entity/afterSave.js
+++ b/entity/VisitPlanEntry_entity/afterSave.js
@@ -18,7 +18,8 @@ if(vars.get("$param.CurrentContext_param") != null)
         newWhere("VISITRECOMMENDATION.VISITRECOMMENDATIONID", savedData["VISITRECOMMENDATION_ID"])
             .updateData(true, "VISITRECOMMENDATION", ["STATUS"], null, ["PLANNED"]);
     }
-    if(savedData["STATUS_APPOINTMENT"] == $KeywordRegistry.visitPlanEntryStatusAppointment$confirmed())
+    if(savedData["STATUS_APPOINTMENT"] == $KeywordRegistry.visitPlanEntryStatusAppointment$confirmed()
+        && !savedData["APPOINTMENT_ID"])
     {
         var summary = translate.text("Site visit") + " | " + savedData["CONTACT_ID.displayValue"];
         var description = savedData["CONTACT_ID.displayValue"];
@@ -34,19 +35,24 @@ if(vars.get("$param.CurrentContext_param") != null)
         var end = new Date(datetime.today(vars.get("$sys.timezone")) + Number(savedData["END_TIME"]));
      
         var links = [
-        {
-            "OBJECT_ID": savedData["ORGANISATION_CONTACT_ID"],
-            "OBJECT_TYPE": "Organisation"
-        },
-        {
-            "OBJECT_ID": savedData["CONTACT_ID"],
-            "OBJECT_TYPE": "Person"
-        }
+            {
+                "OBJECT_ID": savedData["ORGANISATION_CONTACT_ID"],
+                "OBJECT_TYPE": "Organisation"
+            },
+            {
+                "OBJECT_ID": savedData["CONTACT_ID"],
+                "OBJECT_TYPE": "Person"
+            },
+            {
+                "OBJECT_ID" : vars.get("$field.VISITPLANENTRYID"),
+                "OBJECT_TYPE" : "Visitplanentry"
+            }
         ]
     
         var params = {
             "Entry_param" : JSON.stringify(CalendarUtil.createEntry(summary, description, links, undefined, undefined, 
-                            start, end, undefined, undefined, undefined, [standardMail], undefined, undefined, undefined))
+                            start, end, undefined, undefined, undefined, [standardMail], undefined, undefined, undefined)),
+            "Visitplanentry_param": vars.get("$field.VISITPLANENTRYID")
         };
     
         neon.openContext("Appointment", "AppointmentEdit_view", [vars.get("$field.VISITPLANENTRYID")], neon.OPERATINGSTATE_NEW, params, null);
diff --git a/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/documentation.adoc b/entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/documentation.adoc
similarity index 100%
rename from entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/documentation.adoc
rename to entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/documentation.adoc
diff --git a/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/onActionProcess.js b/entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/onActionProcess.js
similarity index 100%
rename from entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/onActionProcess.js
rename to entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/onActionProcess.js
diff --git a/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/stateProcess.js b/entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/stateProcess.js
similarity index 100%
rename from entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/stateProcess.js
rename to entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/stateProcess.js
diff --git a/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/tooltipProcess.js b/entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/tooltipProcess.js
similarity index 100%
rename from entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/opendayroute/tooltipProcess.js
rename to entity/VisitPlanEntry_entity/entityfields/actiongroupopendayroute/children/opendayroute/tooltipProcess.js
diff --git a/entity/VisitPlanEntry_entity/entityfields/appointment_begin_time/valueProcess.js b/entity/VisitPlanEntry_entity/entityfields/appointment_begin_time/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..59376cfc89ef3da86ac092eefd1ddb6446a373c1
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/appointment_begin_time/valueProcess.js
@@ -0,0 +1,17 @@
+import("system.result");
+import("system.calendars");
+import("system.vars");
+
+var appointmentId = vars.get("$field.APPOINTMENT_ID");
+var entryBegin = "";
+
+if(appointmentId)
+{
+    var entry = calendars.getEntry(appointmentId, null, null);
+    if(entry)
+    {
+        entryBegin = entry[calendars.DTSTART];
+    }
+}
+
+result.string(entryBegin);
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/appointment_end_time/valueProcess.js b/entity/VisitPlanEntry_entity/entityfields/appointment_end_time/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..0adc62813e86573e758178ef3bb2a5a06346233d
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/appointment_end_time/valueProcess.js
@@ -0,0 +1,17 @@
+import("system.vars");
+import("system.result");
+import("system.calendars");
+
+var appointmentId = vars.get("$field.APPOINTMENT_ID");
+var entryEnd = "";
+
+if(appointmentId)
+{
+    var entry = calendars.getEntry(appointmentId, null, null);
+    if(entry)
+    {
+        entryEnd = entry[calendars.DTEND];
+    }
+}
+
+result.string(entryEnd);
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/appointment_id/displayValueProcess.js b/entity/VisitPlanEntry_entity/entityfields/appointment_id/displayValueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..4b55485e955cdf543f5925d0d8d9bdd78033d946
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/appointment_id/displayValueProcess.js
@@ -0,0 +1,17 @@
+import("system.vars");
+import("system.result");
+import("system.calendars");
+
+var appointmentId = vars.get("$field.APPOINTMENT_ID");
+var entrySubject = "";
+
+if(appointmentId)
+{
+    var entry = calendars.getEntry(appointmentId, null, null);
+    if(entry)
+    {
+        entrySubject = entry[calendars.SUMMARY];
+    }    
+}
+
+result.string(entrySubject);
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/appointment_status/displayValueProcess.js b/entity/VisitPlanEntry_entity/entityfields/appointment_status/displayValueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..501e8c287a593ed44ade2e50fb86aacebf257848
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/appointment_status/displayValueProcess.js
@@ -0,0 +1,5 @@
+import("Appointment_lib");
+import("system.vars");
+import("system.result");
+
+result.string(AppointmentUtils.getAppointmentStatusDisplayValue(vars.get("$field.APPOINTMENT_STATUS")));
diff --git a/entity/VisitPlanEntry_entity/entityfields/appointment_status/valueProcess.js b/entity/VisitPlanEntry_entity/entityfields/appointment_status/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..1eab30e3e7cada0bc32ee62392037a5318003bc0
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/appointment_status/valueProcess.js
@@ -0,0 +1,17 @@
+import("system.vars");
+import("system.result");
+import("system.calendars");
+
+var appointmentId = vars.get("$field.APPOINTMENT_ID");
+var entryStatus = "";
+
+if(appointmentId)
+{
+    var entry = calendars.getEntry(appointmentId, null, null);
+    if(entry)
+    {
+        entryStatus = entry[calendars.STATUS];
+    }
+}
+
+result.string(entryStatus);
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/appointment_subject/valueProcess.js b/entity/VisitPlanEntry_entity/entityfields/appointment_subject/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f6073cee42e92282b6ff436f7faadc973dfa34e
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/appointment_subject/valueProcess.js
@@ -0,0 +1,17 @@
+import("system.vars");
+import("system.result");
+import("system.calendars");
+
+var appointmentId = vars.get("$field.APPOINTMENT_ID");
+var entrySubject = "";
+
+if(appointmentId)
+{
+    var entry = calendars.getEntry(appointmentId, null, null);
+    if(entry)
+    {
+        entrySubject = entry[calendars.SUMMARY]
+    }
+}
+
+result.string(entrySubject);
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/appointments/children/linkedobjectid_param/valueProcess.js b/entity/VisitPlanEntry_entity/entityfields/appointments/children/linkedobjectid_param/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..58dc9fe9269f10ddc49c176ed1cb66640c4d1652
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/appointments/children/linkedobjectid_param/valueProcess.js
@@ -0,0 +1,4 @@
+import("system.result");
+import("system.vars");
+
+result.string(vars.get("$field.VISITPLANENTRYID"));
diff --git a/entity/VisitPlanEntry_entity/entityfields/appointments/children/visitplanentry_param/valueProcess.js b/entity/VisitPlanEntry_entity/entityfields/appointments/children/visitplanentry_param/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..599bfc35195077f2fb171156ddaf1faddd9b3254
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/appointments/children/visitplanentry_param/valueProcess.js
@@ -0,0 +1,3 @@
+import("system.result");
+
+result.string(true)
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newactivity/onActionProcess.js b/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newactivity/onActionProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..c60ce530547d56cd0fa884f242ea5e70072aa096
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newactivity/onActionProcess.js
@@ -0,0 +1,31 @@
+import("Sql_lib");
+import("AttributeRegistry_basic");
+import("system.db");
+import("KeywordRegistry_basic");
+import("Contact_lib");
+import("Employee_lib");
+import("system.vars");
+import("ActivityTask_lib");
+
+var links = [];
+
+var pointOfContact = newSelect("CONTACT.CONTACTID", db.getCurrentAlias())
+                                .from("CONTACT")
+                                .leftJoin("AB_ATTRIBUTERELATION", "CONTACT.CONTACTID = AB_ATTRIBUTERELATION.OBJECT_ROWID")
+                                .leftJoin("AB_ATTRIBUTE", "AB_ATTRIBUTE.AB_ATTRIBUTEID = AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID")
+                                .leftJoin("ORGANISATION", "ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID")
+                                .where("AB_ATTRIBUTE.AB_ATTRIBUTEID", $AttributeRegistry.visitPlanPointOfContact()) 
+                                .and("CONTACT.CONTACTID", vars.get("$field.ORGANISATION_CONTACT_ID"))
+                                .cell();
+
+if(pointOfContact)
+{
+    links.push([ContactUtils.getContextByContactId(pointOfContact), pointOfContact]);
+}
+else
+{
+    links.push(["Organisation", vars.get("$field.ORGANISATION_CONTACT_ID")]);
+    links.push(["Person", vars.get("$field.CONTACT_ID")]);
+}
+
+ActivityUtils.createNewActivity(null, links, null, null, null, null, $KeywordRegistry.activityDirection$outgoing(), null, $KeywordRegistry.activityCategory$visit(), vars.get("$field.ENTRYDATE"), vars.get("$field.VISITPLANENTRYID"));
diff --git a/entity/VisitPlanEntry_entity/entityfields/newappointment/stateProcess.js b/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newactivity/stateProcess.js
similarity index 63%
rename from entity/VisitPlanEntry_entity/entityfields/newappointment/stateProcess.js
rename to entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newactivity/stateProcess.js
index 5a2727774f69cea4ca520a5813e9502a4869de5c..8581fdf93ca064ac768d8113e9c8c766e8daea69 100644
--- a/entity/VisitPlanEntry_entity/entityfields/newappointment/stateProcess.js
+++ b/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newactivity/stateProcess.js
@@ -1,9 +1,12 @@
+import("system.datetime");
 import("system.result");
 import("system.vars");
 import("system.neon");
 
 var state = neon.COMPONENTSTATE_DISABLED;
-if (vars.get("$sys.selectionRows") != "" && vars.get("$sys.selectionRows") != undefined)
+var today = vars.get("$sys.date")
+
+if (vars.get("$field.ENTRYDATE") <= today)
 {
     state = neon.COMPONENTSTATE_EDITABLE;
 }
diff --git a/entity/VisitPlanEntry_entity/entityfields/newappointment/onActionProcess.js b/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newappointment/onActionProcess.js
similarity index 54%
rename from entity/VisitPlanEntry_entity/entityfields/newappointment/onActionProcess.js
rename to entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newappointment/onActionProcess.js
index 7bf8461c01ec469ee6d667c1211272b8aa4bf7f7..83fecbf4027d00083386105c9376ddb71f66c591 100644
--- a/entity/VisitPlanEntry_entity/entityfields/newappointment/onActionProcess.js
+++ b/entity/VisitPlanEntry_entity/entityfields/entityactiongroup/children/newappointment/onActionProcess.js
@@ -1,51 +1,53 @@
-import("system.translate");
-import("system.datetime");
-import("system.calendars");
-import("system.eMath");
-import("system.util");
-import("system.db");
-import("system.vars");
-import("system.neon");
 import("system.result");
-import("Communication_lib");
+import("system.neon");
 import("Calendar_lib");
-import("Contact_lib")
+import("system.datetime");
+import("Communication_lib");
+import("system.translate");
+import("Contact_lib");
 import("Sql_lib");
+import("system.vars");
 
 var selectionRowData = vars.get("$sys.selectionRows");
 
-if(selectionRowData[0].VISITRECOMMENDATION_ID)
+if(vars.get("$field.VISITRECOMMENDATION_ID"))
 {
-    newWhere("VISITRECOMMENDATION.VISITRECOMMENDATIONID", selectionRowData[0].VISITRECOMMENDATION_ID)
+    newWhere("VISITRECOMMENDATION.VISITRECOMMENDATIONID", vars.get("$field.VISITRECOMMENDATION_ID"))
             .updateData(true, "VISITRECOMMENDATION", ["STATUS"], null, ["PLANNED"]);
 }
 
-var fullName = ContactUtils.getFullTitleByContactId(selectionRowData[0].CONTACT_ID, true)
+var fullName = ContactUtils.getFullTitleByContactId(vars.get("$field.CONTACT_ID"), true)
 var summary = translate.text("Site visit") + " || " + fullName;
 var description = fullName;
-var standardMail = CommUtil.getStandardMail(selectionRowData[0].CONTACT_ID); 
+var standardMail = CommUtil.getStandardMail(vars.get("$field.CONTACT_ID")); 
 
 //creates an js date object with the current utc time and adds the appointment begin/end time.
 //necessary for CalendarUtil.createEntry() 
-var entryDate = Number(datetime.toLong(datetime.toDate(Number(selectionRowData[0].ENTRYDATE), "dd.MM.yyyy"), "dd.MM.yyyy"));
-var start = new Date(entryDate + Number(selectionRowData[0].BEGIN_TIME));
-var end = new Date(entryDate + Number(selectionRowData[0].END_TIME));
+var entrydate = Number(datetime.toLong(datetime.toDate(Number(vars.get("$field.ENTRYDATE")), "dd.MM.yyyy"), "dd.MM.yyyy"))
+var start = new Date(entrydate + Number(vars.get("$field.BEGIN_TIME")));
+var end = new Date(entrydate + Number(vars.get("$field.END_TIME")));
 
 var links = [
                 {
-                    "OBJECT_ID" : selectionRowData[0]["ORGANISATION_CONTACT_ID"],
+                    "OBJECT_ID" : vars.get("$field.ORGANISATION_CONTACT_ID"),
                     "OBJECT_TYPE" : "Organisation"
                 },
                 {
-                    "OBJECT_ID" : selectionRowData[0]["CONTACT_ID"],
+                    "OBJECT_ID" : vars.get("$field.CONTACT_ID"),
                     "OBJECT_TYPE" : "Person"
+                },
+                {
+                    "OBJECT_ID" : vars.get("$field.VISITPLANENTRYID"),
+                    "OBJECT_TYPE" : "Visitplanentry"
                 }
+                
 ];
 
 var params = {
     "Entry_param": JSON.stringify(CalendarUtil.createEntry(summary, description, links, undefined, undefined, start,
                                                                 end, undefined, undefined, undefined, [standardMail], 
-                                                                undefined, undefined, undefined))
+                                                                undefined, undefined, undefined)),
+    "Visitplanentry_param": vars.get("$field.VISITPLANENTRYID")
 };
 
 neon.openContext("Appointment", "AppointmentEdit_view", [vars.get("$field.VISITPLANENTRYID")], neon.OPERATINGSTATE_NEW, params, null);
diff --git a/entity/VisitPlanEntry_entity/entityfields/newappointment/documentation.adoc b/entity/VisitPlanEntry_entity/entityfields/newappointment/documentation.adoc
deleted file mode 100644
index 51e093f5d14cc0e2bf39de625536c213e16e22e8..0000000000000000000000000000000000000000
--- a/entity/VisitPlanEntry_entity/entityfields/newappointment/documentation.adoc
+++ /dev/null
@@ -1 +0,0 @@
-creates the Appointment-editview
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/newappointment/tooltipProcess.js b/entity/VisitPlanEntry_entity/entityfields/newappointment/tooltipProcess.js
deleted file mode 100644
index ea083fcb476a7c75a6494b1b17d913cc5a62ad90..0000000000000000000000000000000000000000
--- a/entity/VisitPlanEntry_entity/entityfields/newappointment/tooltipProcess.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import("system.translate");
-import("system.result");
-
-result.string(translate.text("Create new Appointment"));
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/sync/children/syncappointmenttoplan/onActionProcess.js b/entity/VisitPlanEntry_entity/entityfields/sync/children/syncappointmenttoplan/onActionProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..e0bcb2bde5fa180b19cd0a58080caef44d0983ea
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/sync/children/syncappointmenttoplan/onActionProcess.js
@@ -0,0 +1,74 @@
+import("system.neon");
+import("system.db");
+import("system.util");
+import("Sql_lib");
+import("Employee_lib");
+import("system.datetime");
+import("system.vars");
+
+var selectionRowData = vars.get("$sys.selectionRows");
+
+var planId = selectionRowData[0].VISITPLANENTRYID
+var appId = selectionRowData[0].APPOINTMENT_ID
+
+var appEntryDate = datetime.toLong(datetime.toDate(selectionRowData[0].APPOINTMENT_BEGIN_TIME, "yyyy-MM-dd"), "yyyy-MM-dd", "UTC");
+var appBeginTime = datetime.toDate(selectionRowData[0].APPOINTMENT_BEGIN_TIME, "HH:mm:ss.S"); // #1076044 set tz to prevent time gaps.
+appBeginTime = datetime.toLong(appBeginTime, "HH:mm:ss.S", "UTC");
+var appEndTime = datetime.toDate(selectionRowData[0].APPOINTMENT_END_TIME, "HH:mm:ss.S"); // #1076044 set tz to prevent time gaps.
+appEndTime = datetime.toLong(appEndTime, "HH:mm:ss.S", "UTC");
+    
+var user = EmployeeUtils.getCurrentContactId()
+var calendarWeek = datetime.toLocaleDate(appEntryDate, "w");
+var calendarYear = datetime.toLocaleDate(appEntryDate, "yyyy");
+var weekId = newSelect("VISITPLANEMPLOYEEWEEKID")
+.from("VISITPLANEMPLOYEEWEEK") 
+.where("VISITPLANEMPLOYEEWEEK.VISITPLAN_WEEK", calendarWeek)
+.and("VISITPLANEMPLOYEEWEEK.VISITPLAN_YEAR", calendarYear)
+.and("VISITPLANEMPLOYEEWEEK.CONTACT_ID", user)
+.cell();
+
+if(weekId)
+{
+    visitPlanEmployeeWeekID = weekId;
+}
+else
+{
+    var newWeekId = util.getNewUUID();
+
+    var valuesWeek = [
+    newWeekId,
+    calendarWeek,
+    calendarYear,
+    user
+    ];
+
+    var columnsWeek = [
+    "VISITPLANEMPLOYEEWEEKID",
+    "VISITPLAN_WEEK",
+    "VISITPLAN_YEAR",
+    "CONTACT_ID",
+    ];
+
+    db.insertData("VISITPLANEMPLOYEEWEEK", columnsWeek, null, valuesWeek);
+
+    visitPlanEmployeeWeekID = newWeekId;
+}    
+
+var values = [
+appEntryDate,
+appBeginTime,
+appEndTime,
+visitPlanEmployeeWeekID
+];
+
+var columns = [
+"ENTRYDATE",
+"BEGIN_TIME",
+"END_TIME",
+"VISITPLANEMPLOYEEWEEK_ID"
+];
+
+var cond = newWhere("VISITPLANENTRY.VISITPLANENTRYID", planId).toString();
+db.updateData("VISITPLANENTRY", columns, null, values, cond);
+ 
+neon.refreshAll();
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/sync/children/syncplantoappointment/onActionProcess.js b/entity/VisitPlanEntry_entity/entityfields/sync/children/syncplantoappointment/onActionProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..4cab1fb757d71ca0e38ba31699535bb6107bc41b
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/sync/children/syncplantoappointment/onActionProcess.js
@@ -0,0 +1,20 @@
+import("system.neon");
+import("system.datetime");
+import("system.calendars");
+import("system.vars");
+
+var selectionRowData = vars.get("$sys.selectionRows")[0];
+
+var entry = calendars.getEntry(selectionRowData.APPOINTMENT_ID, null, null, calendars.VEVENT);
+
+var planEntryDate = datetime.toDate(selectionRowData.ENTRYDATE, "dd-MM-yyyy");
+var planBeginTime = planEntryDate + " " + datetime.toDate(selectionRowData.BEGIN_TIME, "HH:mm:ss.S", "UTC");
+    planBeginTime = datetime.toLong(planBeginTime, "dd-MM-yyyy HH:mm:ss.S"); // #1076044 set tz to prevent time gaps.
+var planEndTime = planEntryDate + " " + datetime.toDate(selectionRowData.END_TIME, "HH:mm:ss.S", "UTC");
+    planEndTime = datetime.toLong(planEndTime, "dd-MM-yyyy HH:mm:ss.S"); // #1076044 set tz to prevent time gaps.
+
+entry[calendars.DTSTART] = planBeginTime;
+entry[calendars.DTEND] = planEndTime;
+
+calendars.updateEntry(entry);
+neon.refreshAll();
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/sync/stateProcess.js b/entity/VisitPlanEntry_entity/entityfields/sync/stateProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..3eb0bebce5c04df5f7cab33409c0b763d847db66
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/sync/stateProcess.js
@@ -0,0 +1,23 @@
+import("system.result");
+import("Sql_lib");
+import("system.vars");
+import("Employee_lib");
+import("system.neon");
+
+var state = neon.COMPONENTSTATE_DISABLED;
+var contactId = EmployeeUtils.getCurrentContactId();
+var weekplanUser = newSelect("CONTACT_ID").from("VISITPLANEMPLOYEEWEEK")
+              .where("VISITPLANEMPLOYEEWEEK.VISITPLANEMPLOYEEWEEKID", vars.get("$field.VISITPLANEMPLOYEEWEEK_ID"))
+              .cell();
+              
+var selection = vars.get("$sys.selectionRows")[0]
+
+if(selection && selection.APPOINTMENT_ID)
+{
+    if(selection.ISGROUP != "true" && weekplanUser == contactId)
+    {
+        state = neon.COMPONENTSTATE_EDITABLE;
+    }    
+}
+
+result.string(state)
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/syncicon/colorProcess.js b/entity/VisitPlanEntry_entity/entityfields/syncicon/colorProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..b8b288b7090935877e745466616cc4e3b17acd6c
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/syncicon/colorProcess.js
@@ -0,0 +1,12 @@
+import("system.vars");
+import("system.result");
+import("system.neon")
+
+if(vars.get("$field.syncIcon") == "VAADIN:CLOSE_CIRCLE_O")
+{
+    result.string(neon.PRIORITY_HIGH_COLOR);
+}
+else
+{
+    result.string(neon.PRIORITY_LOW_COLOR);
+}
\ No newline at end of file
diff --git a/entity/VisitPlanEntry_entity/entityfields/syncicon/valueProcess.js b/entity/VisitPlanEntry_entity/entityfields/syncicon/valueProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..c8fee46bc43943a3c25e7d9e3a417a5ff355f049
--- /dev/null
+++ b/entity/VisitPlanEntry_entity/entityfields/syncicon/valueProcess.js
@@ -0,0 +1,26 @@
+import("system.datetime");
+import("system.result");
+import("system.vars");
+
+var appEntryDate = datetime.toLong(datetime.toDate(vars.get("$field.APPOINTMENT_BEGIN_TIME"), "yyyy-MM-dd"), "yyyy-MM-dd", "UTC");
+var appBeginTime = datetime.toDate(vars.get("$field.APPOINTMENT_BEGIN_TIME"), "HH:mm:ss.S"); // #1076044 set tz to prevent time gaps.
+    appBeginTime = datetime.toLong(appBeginTime, "HH:mm:ss.S", "UTC");
+var appEndTime = datetime.toDate(vars.get("$field.APPOINTMENT_END_TIME"), "HH:mm:ss.S"); // #1076044 set tz to prevent time gaps.
+    appEndTime = datetime.toLong(appEndTime, "HH:mm:ss.S", "UTC");
+
+var planEntryDate = vars.get("$field.ENTRYDATE");
+var planBeginTime = vars.get("$field.BEGIN_TIME");
+var planEndTime = vars.get("$field.END_TIME");
+
+if(vars.get("$field.ISGROUP") == "true")
+{
+    result.string("");
+}
+else if(planEntryDate != appEntryDate || appBeginTime != planBeginTime || appEndTime != planEndTime)
+{
+    result.string("VAADIN:CLOSE_CIRCLE_O");
+}
+else if(planEntryDate == appEntryDate || appBeginTime == planBeginTime || appEndTime == planEndTime)
+{
+    result.string("VAADIN:CHECK_CIRCLE_O");
+}
diff --git a/entity/VisitPlanEntry_entity/recordcontainers/db/onDBInsert.js b/entity/VisitPlanEntry_entity/recordcontainers/db/onDBInsert.js
index d8f73c57c0fef0051eabac2e39753abf67b548b8..da512da8a8f734095375d68d9a18d75dca29a9a0 100644
--- a/entity/VisitPlanEntry_entity/recordcontainers/db/onDBInsert.js
+++ b/entity/VisitPlanEntry_entity/recordcontainers/db/onDBInsert.js
@@ -8,9 +8,11 @@ import("system.util");
 
 var visitPlanEmployeeWeekID = "";
 var insertData = [];
-var user = EmployeeUtils.getCurrentContactId();
+var contactId = EmployeeUtils.getCurrentContactId();
 if(vars.get("$param.Entries_param") != null)
+{
     visitPlanEmployeeWeekID = vars.get("$param.Entries_param");
+}
 else
 {
     var calendarWeek = datetime.toLocaleDate(vars.get("$field.ENTRYDATE"), "w");
@@ -19,11 +21,13 @@ else
     .from("VISITPLANEMPLOYEEWEEK") 
     .where("VISITPLANEMPLOYEEWEEK.VISITPLAN_WEEK", calendarWeek)
     .and("VISITPLANEMPLOYEEWEEK.VISITPLAN_YEAR", calendarYear)
-    .and("VISITPLANEMPLOYEEWEEK.CONTACT_ID", user)
+    .and("VISITPLANEMPLOYEEWEEK.CONTACT_ID", contactId)
     .cell();
 
     if(weekId)
+    {
         visitPlanEmployeeWeekID = weekId;
+    }
     else
     {
         var newWeekId = util.getNewUUID();
@@ -32,7 +36,7 @@ else
         newWeekId,
         calendarWeek,
         calendarYear,
-        user
+        contactId
         ];
 
         var columnsWeek = [
@@ -46,34 +50,8 @@ else
 
         visitPlanEmployeeWeekID = newWeekId;
     }    
-}
-
-if(vars.get("$param.NoVisitPlanEmployeeWeek_param")){
-    var valuesEntry = [
-    util.getNewUUID(),
-    vars.get("$field.ENTRYDATE"),
-    vars.get("$field.BEGIN_TIME"),
-    vars.get("$field.END_TIME"),
-    vars.get("$field.ORGANISATION_CONTACT_ID"),
-    vars.get("$field.CONTACT_ID"),
-    visitPlanEmployeeWeekID,
-    vars.get("$field.STATUS"),
-    vars.get("$field.STATUS_APPOINTMENT"),
-    vars.get("$field.VISITRECOMMENDATION_ID"),
-    ];
-
-    var columnsEntry = [
-    "VISITPLANENTRYID",
-    "ENTRYDATE",
-    "BEGIN_TIME",
-    "END_TIME",
-    "ORGANISATION_CONTACT_ID",
-    "CONTACT_ID",
-    "VISITPLANEMPLOYEEWEEK_ID",
-    "STATUS",
-    "STATUS_APPOINTMENT",
-    "VISITRECOMMENDATION_ID"
-    ];
-
-    db.insertData("VISITPLANENTRY", columnsEntry, null, valuesEntry);
+    
+    var updateEntry = newWhere("VISITPLANENTRY.VISITPLANENTRYID", vars.get("$local.uid"))
+    .updateData(true, "VISITPLANENTRY", ["VISITPLANEMPLOYEEWEEK_ID"], null, [visitPlanEmployeeWeekID]);
+    
 }
\ No newline at end of file
diff --git a/entity/VisitRecommendation_entity/entityfields/newentrygroup/children/newvisitplaneentry/onActionProcess.js b/entity/VisitRecommendation_entity/entityfields/newentrygroup/children/newvisitplaneentry/onActionProcess.js
index 373517b099005b28f7a2c375313397defada0f8b..cf79e9774522847b458a6ef8fd04e2ee74d9ad15 100644
--- a/entity/VisitRecommendation_entity/entityfields/newentrygroup/children/newvisitplaneentry/onActionProcess.js
+++ b/entity/VisitRecommendation_entity/entityfields/newentrygroup/children/newvisitplaneentry/onActionProcess.js
@@ -12,4 +12,4 @@ params["Entrydate_param"] = vars.get("$field.DUE_DATE");
 params["PrioritySource_param"] = vars.get("$field.PRIORITY_SOURCE");
 params["VisitrecommendationId_param"] = vars.get("$field.UID");
 
-neon.openContext("VisitPlanEntry", null, null, neon.OPERATINGSTATE_NEW, params);
\ No newline at end of file
+neon.openContext("VisitPlanEntry", "VisitPlanEntryEdit_view", null, neon.OPERATINGSTATE_NEW, params);
\ No newline at end of file
diff --git a/entity/VisitRecommendation_entity/recordcontainers/jdito/contentProcess.js b/entity/VisitRecommendation_entity/recordcontainers/jdito/contentProcess.js
index 19858910ea9c252784d9c696e9aa637ea54c3c5b..bf1b5d5cc55efbf7fbc7e01d7abb471e72ffa385 100644
--- a/entity/VisitRecommendation_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/VisitRecommendation_entity/recordcontainers/jdito/contentProcess.js
@@ -1,3 +1,4 @@
+import("VisitPlanning_lib");
 import("JditoFilter_lib");
 import("system.eMath");
 import("system.tools");
@@ -73,7 +74,7 @@ for( let i = 0; i < recommendationSQLData.length; i++)
     }    
     else if(recommendationSQLData[i][3])
     {
-        prio = getPrioByDueDate(recommendationSQLData[i][3]);
+        prio = VisitPlanningUtils.getPrioByDueDate(recommendationSQLData[i][3]);
     }    
     else
     {
@@ -197,9 +198,9 @@ if(idValues == false)
             visitFrequencyData[i][4], //COUNTRY.value
             visitFrequencyData[i][5], //ZIP.value
             visitFrequencyData[i][6], //CITY.value
-            getPrioByDueDate(dueDate), //PRIORITY.value
+            VisitPlanningUtils.getPrioByDueDate(dueDate), //PRIORITY.value
             $KeywordRegistry.visitRecommendationPrioSource$visitFrequency(), //PRIORITY_SOURCE.value
-            KeywordUtils.getViewValue($KeywordRegistry.visitRecommendationPriority(), getPrioByDueDate(dueDate)), //PRIORITY.displayValue
+            KeywordUtils.getViewValue($KeywordRegistry.visitRecommendationPriority(), VisitPlanningUtils.getPrioByDueDate(dueDate)), //PRIORITY.displayValue
             dueDate, //DUE_DATE.value
             "", //INFO.value
             visitFrequencyData[i][1], //CONTACT_ID.value
@@ -217,35 +218,13 @@ if(idValues == false)
 
         ];
         
+       var frequencyIsRecommendation = VisitPlanningUtils.checkIfFrequencyIsRecommendation(tmpData[0], vars.get("$param.PrioritySource_param"))
         
-        var manualRec = newSelect("VISITRECOMMENDATION.VISITRECOMMENDATIONID")
-        .from("VISITRECOMMENDATION")
-        .where("VISITRECOMMENDATION.CONTACT_ID", tmpData[0])
-        .or("VISITRECOMMENDATION.CONTACT_PERSON_ID", tmpData[0])
-        .cell()
-        
-        var visitEntry = newSelect("VISITPLANENTRY.VISITPLANENTRYID")
-        .from("VISITPLANENTRY")
-        .where(newWhere("VISITPLANENTRY.CONTACT_ID", tmpData[0])
-            .or("VISITPLANENTRY.ORGANISATION_CONTACT_ID", tmpData[0]))
-        
-       var visitEntryExists = visitEntry.cell();
-       
-       visitEntry = visitEntry.and(newWhere("VISITPLANENTRY.ENTRYDATE", eMath.subInt(vars.get("$sys.today"), datetime.ONE_DAY * 7), SqlBuilder.LESS_OR_EQUAL())
-            .and("VISITPLANENTRY.STATUS", $KeywordRegistry.visitPlanEntryStatus$Visitreportcreated(), SqlBuilder.NOT_EQUAL()))
-            .or("VISITPLANENTRY.STATUS", $KeywordRegistry.visitPlanEntryStatus$Visitreportcreated(), SqlBuilder.EQUAL())
-            .cell()
-            
-       var prioritySource = vars.get("$param.PrioritySource_param");
-       
-       if(prioritySource != $KeywordRegistry.visitRecommendationPrioSource$manual() && !manualRec) //if manual Record was created, visitfrequency is not relevant
-       {
-           //!visitEntryExists - if no visitplanentry for the organisation/person from recommendation was created -> show recommendation so it can be planned
-           if(!visitEntryExists || visitEntry)
-           {    
-               recommendationData.push(tmpData);
-           }
+       if(frequencyIsRecommendation)
+       {    
+           recommendationData.push(tmpData);
        }
+       
     }
 }
 
@@ -307,37 +286,3 @@ if (!sortOrder.length)
 
 ArrayUtils.sortMulti(recommendationData, sortOrder);
 result.object(recommendationData);
-
-function getPrioByDueDate(pDueDate)
-{
-    var prio = "";
-    var currentDate = datetime.date();
-    
-    if(pDueDate != "")
-    {
-        var dateDifference = pDueDate - currentDate;
-
-        if(dateDifference < 0)
-        {
-            prio = $KeywordRegistry.visitRecommendationPriority$critical();
-        }    
-        else if(dateDifference < datetime.ONE_DAY * 3)
-        {
-            prio = $KeywordRegistry.visitRecommendationPriority$veryHigh();
-        }    
-        else if(dateDifference < datetime.ONE_DAY * 7)
-        {
-            prio = $KeywordRegistry.visitRecommendationPriority$high();
-        }    
-        else if(dateDifference < datetime.ONE_DAY * 14)
-        {
-            prio = $KeywordRegistry.visitRecommendationPriority$medium();
-        }    
-        else
-        {
-            prio = $KeywordRegistry.visitRecommendationPriority$low();
-        }    
-    }
-    
-    return prio;
-}
\ No newline at end of file
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index cbddf7d6d2aec500ca25b82f6e9ec27c814c7f29..d90f07cdbf9d3429a81be929767b18e005b5a027 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -9520,6 +9520,90 @@
     <entry>
       <key>Campaignstep has already ended</key>
     </entry>
+    <entry>
+      <key>Opener rate (in \%)</key>
+    </entry>
+    <entry>
+      <key>Open Admin View</key>
+    </entry>
+    <entry>
+      <key>Remove recipients with advertising appeal</key>
+    </entry>
+    <entry>
+      <key>Attendees</key>
+    </entry>
+    <entry>
+      <key>Grouptask</key>
+    </entry>
+    <entry>
+      <key>District contact assigned</key>
+    </entry>
+    <entry>
+      <key>All tasks that are not completed and assigned to me</key>
+    </entry>
+    <entry>
+      <key>Mailing</key>
+    </entry>
+    <entry>
+      <key>This year</key>
+    </entry>
+    <entry>
+      <key>Attendees cannot be assigned repeatedly!</key>
+    </entry>
+    <entry>
+      <key>Salesproject: Role</key>
+    </entry>
+    <entry>
+      <key>Appointments/Tasks</key>
+    </entry>
+    <entry>
+      <key>Click rate (in \%)</key>
+    </entry>
+    <entry>
+      <key>Open Route of the day</key>
+    </entry>
+    <entry>
+      <key>Attendee</key>
+    </entry>
+    <entry>
+      <key>was missed</key>
+    </entry>
+    <entry>
+      <key>Verknüpfungen</key>
+    </entry>
+    <entry>
+      <key>Task Attendees</key>
+    </entry>
+    <entry>
+      <key>KeywordTest3</key>
+    </entry>
+    <entry>
+      <key>KeywordTest4</key>
+    </entry>
+    <entry>
+      <key>KeywordTest5</key>
+    </entry>
+    <entry>
+      <key>KeywordTest1</key>
+    </entry>
+    <entry>
+      <key>Einzelaufgaben erstellen</key>
+    </entry>
+    <entry>
+      <key>My Tasks</key>
+    </entry>
+    <entry>
+      <key>Mailing missed</key>
+    </entry>
+    <entry>
+      <key>Departments cannot be assigned repeatedly!</key>
+    </entry>
+    <entry>
+      <key>Erledigt setzen</key>
+    </entry>
+    <entry>
+      <key>Unique click rate (in \%)</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 2dc7d4f6088ee51dbaf1fdce45c55c888e718dbc..f5455a9e3a103f5c3f1dfde55ec22122e3728a27 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -42,6 +42,10 @@
       <key>Default phone</key>
       <value>Standard Telefon</value>
     </entry>
+    <entry>
+      <key>Preparation</key>
+      <value>Vorbereitung</value>
+    </entry>
     <entry>
       <key>Open Turnover</key>
       <value>Umsatzprognose öffnen</value>
@@ -302,6 +306,10 @@
       <key>Checklist entries</key>
       <value>Checklisteneinträge</value>
     </entry>
+    <entry>
+      <key>Monday</key>
+      <value>Montag</value>
+    </entry>
     <entry>
       <key>Organisation: Classification</key>
       <value>Firma: Klassifizierung</value>
@@ -978,6 +986,10 @@
       <key>Open tasks</key>
       <value>Offene Aufgaben</value>
     </entry>
+    <entry>
+      <key>synchronize Appointment to Plan</key>
+      <value>Daten aus Termin in Planung übernehmen</value>
+    </entry>
     <entry>
       <key>My Forecast</key>
       <value>Mein Forecast</value>
@@ -2864,7 +2876,6 @@
     </entry>
     <entry>
       <key>copy</key>
-      <value>Kopie</value>
     </entry>
     <entry>
       <key>Person</key>
@@ -2880,7 +2891,6 @@
     </entry>
     <entry>
       <key>Copy Recipients</key>
-      <value>Empfänger kopieren</value>
     </entry>
     <entry>
       <key>dd.MM.yyyy</key>
@@ -5007,6 +5017,10 @@
       <key>Completed</key>
       <value>Abgeschlossen</value>
     </entry>
+    <entry>
+      <key>Saturday</key>
+      <value>Samstag</value>
+    </entry>
     <entry>
       <key>In planning</key>
       <value>In Planung</value>
@@ -6905,6 +6919,10 @@
       <key>ORGANISATION_ID</key>
       <value>Firmen ID</value>
     </entry>
+    <entry>
+      <key>Tuesday</key>
+      <value>Dienstag</value>
+    </entry>
     <entry>
       <key>CONTRACTID (UID)</key>
       <value>CONTRACTID (UID)</value>
@@ -9874,6 +9892,10 @@ Bitte Datumseingabe prüfen</value>
       <key>Valid from (as </key>
       <value>gültig ab (in </value>
     </entry>
+    <entry>
+      <key>Sunday</key>
+      <value>Sonntag</value>
+    </entry>
     <entry>
       <key>yellow</key>
       <value>gelb</value>
@@ -10991,6 +11013,10 @@ Bitte Datumseingabe prüfen</value>
       <key>Salesproject phase</key>
       <value>Vertriebsprojektphase</value>
     </entry>
+    <entry>
+      <key>synchronize</key>
+      <value>Synchronisieren</value>
+    </entry>
     <entry>
       <key>Kontext</key>
     </entry>
@@ -10998,6 +11024,10 @@ Bitte Datumseingabe prüfen</value>
       <key>There are no test recipients.</key>
       <value>Es sind keine Testempfänger eingestellt.</value>
     </entry>
+    <entry>
+      <key>synchronize Plan to Appointment</key>
+      <value>Daten aus Planung in Termin übernehmen</value>
+    </entry>
     <entry>
       <key>Trait</key>
       <value>Merkmal</value>
@@ -11538,6 +11568,10 @@ Bitte Datumseingabe prüfen</value>
       <key>Add Manual Delete Flag</key>
       <value>Füge manuelles Löschkennzeichen hinzu</value>
     </entry>
+    <entry>
+      <key>Friday</key>
+      <value>Freitag</value>
+    </entry>
     <entry>
       <key>DSGVO Configuration</key>
       <value>DSGVO Konfiguration</value>
@@ -11735,6 +11769,10 @@ Bitte Datumseingabe prüfen</value>
     <entry>
       <key>Redirect</key>
     </entry>
+    <entry>
+      <key>Wednesday</key>
+      <value>Mittwoch</value>
+    </entry>
     <entry>
       <key>Maillog</key>
     </entry>
@@ -12263,6 +12301,10 @@ Bitte Datumseingabe prüfen</value>
       <key>Bzip2 Archive</key>
       <value>Bzip2 Archiv</value>
     </entry>
+    <entry>
+      <key>Thursday</key>
+      <value>Donnerstag</value>
+    </entry>
     <entry>
       <key>C Shell Script</key>
       <value>C Shell Skript</value>
@@ -12483,15 +12525,6 @@ Bitte Datumseingabe prüfen</value>
       <key>Zip Archive</key>
       <value>Zip Archiv</value>
     </entry>
-    <entry>
-      <key>set attribute (use filter result)</key>
-    </entry>
-    <entry>
-      <key>Copy Recipients</key>
-    </entry>
-    <entry>
-      <key>copy</key>
-    </entry>
     <entry>
       <key>Attendees cannot be assigned repeatedly!</key>
       <value>Teilnehmer können nicht mehrmals zugewiesen werden!</value>
@@ -12554,13 +12587,7 @@ Bitte Datumseingabe prüfen</value>
       <value>Guppenaufgabe</value>
     </entry>
     <entry>
-      <key>DSGVO-Anonymisierung</key>
-    </entry>
-    <entry>
-      <key>privat</key>
-    </entry>
-    <entry>
-      <key>During processing the e-mail an error has occurred.\n Please contact an administrator</key>
+      <key>Remove recipients with communication rejection</key>
     </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index a757ce01763c1a53a7a17f56f827d03c9fc4f900..bcd239647a5472e2c26a46200e8efb00e596650d 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -9368,30 +9368,9 @@
     <entry>
       <key>Weekly</key>
     </entry>
-    <entry>
-      <key>SerialLetter</key>
-    </entry>
-    <entry>
-      <key>Bulkmail</key>
-    </entry>
-    <entry>
-      <key>%0 recipient will be added to the serial letter.</key>
-    </entry>
-    <entry>
-      <key>Volume (Euro)</key>
-    </entry>
-    <entry>
-      <key>%0 recipient will be added to the bulk mail.</key>
-    </entry>
     <entry>
       <key>Copy Recipients</key>
     </entry>
-    <entry>
-      <key>Attribute \"%0\" can only be inserted once with the same value.</key>
-    </entry>
-    <entry>
-      <key>Set attribute (use filter result)</key>
-    </entry>
     <entry>
       <key>copy</key>
     </entry>
@@ -9617,12 +9596,6 @@
     <entry>
       <key>Should a test email be sent to you instead?</key>
     </entry>
-    <entry>
-      <key>Copy Recipients</key>
-    </entry>
-    <entry>
-      <key>copy</key>
-    </entry>
     <entry>
       <key>There are no test recipients.</key>
     </entry>
@@ -9635,6 +9608,90 @@
     <entry>
       <key>Campaignstep has already ended</key>
     </entry>
+    <entry>
+      <key>Opener rate (in \%)</key>
+    </entry>
+    <entry>
+      <key>Open Admin View</key>
+    </entry>
+    <entry>
+      <key>Remove recipients with advertising appeal</key>
+    </entry>
+    <entry>
+      <key>Attendees</key>
+    </entry>
+    <entry>
+      <key>Grouptask</key>
+    </entry>
+    <entry>
+      <key>District contact assigned</key>
+    </entry>
+    <entry>
+      <key>All tasks that are not completed and assigned to me</key>
+    </entry>
+    <entry>
+      <key>Mailing</key>
+    </entry>
+    <entry>
+      <key>This year</key>
+    </entry>
+    <entry>
+      <key>Attendees cannot be assigned repeatedly!</key>
+    </entry>
+    <entry>
+      <key>Salesproject: Role</key>
+    </entry>
+    <entry>
+      <key>Appointments/Tasks</key>
+    </entry>
+    <entry>
+      <key>Click rate (in \%)</key>
+    </entry>
+    <entry>
+      <key>Open Route of the day</key>
+    </entry>
+    <entry>
+      <key>Attendee</key>
+    </entry>
+    <entry>
+      <key>was missed</key>
+    </entry>
+    <entry>
+      <key>Verknüpfungen</key>
+    </entry>
+    <entry>
+      <key>Task Attendees</key>
+    </entry>
+    <entry>
+      <key>KeywordTest3</key>
+    </entry>
+    <entry>
+      <key>KeywordTest4</key>
+    </entry>
+    <entry>
+      <key>KeywordTest5</key>
+    </entry>
+    <entry>
+      <key>KeywordTest1</key>
+    </entry>
+    <entry>
+      <key>Einzelaufgaben erstellen</key>
+    </entry>
+    <entry>
+      <key>My Tasks</key>
+    </entry>
+    <entry>
+      <key>Mailing missed</key>
+    </entry>
+    <entry>
+      <key>Departments cannot be assigned repeatedly!</key>
+    </entry>
+    <entry>
+      <key>Erledigt setzen</key>
+    </entry>
+    <entry>
+      <key>Unique click rate (in \%)</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/neonView/VisitPlanEntryFilter_view/VisitPlanEntryFilter_view.aod b/neonView/VisitPlanEntryFilter_view/VisitPlanEntryFilter_view.aod
index b2d9755026985e22cdd2d98d72430e9654559461..f1cdbf89af4b840ecba70eeba522100e7f9f39eb 100644
--- a/neonView/VisitPlanEntryFilter_view/VisitPlanEntryFilter_view.aod
+++ b/neonView/VisitPlanEntryFilter_view/VisitPlanEntryFilter_view.aod
@@ -38,7 +38,9 @@
       <name>TreeTable</name>
       <parentField>PARENT_ID</parentField>
       <entityField>#ENTITY</entityField>
-      <favoriteActionGroup1>entityActionGroup</favoriteActionGroup1>
+      <favoriteActionGroup1>ActionGroupOpenDayRoute</favoriteActionGroup1>
+      <favoriteActionGroup2></favoriteActionGroup2>
+      <favoriteActionGroup3>sync</favoriteActionGroup3>
       <defaultGroupFields>
         <element>ENTRYDATE</element>
       </defaultGroupFields>
@@ -47,6 +49,10 @@
           <name>d728f2d9-c223-47fd-9372-6f49203f68fd</name>
           <entityField>PARENTNAME</entityField>
         </neonTreeTableColumn>
+        <neonTreeTableColumn>
+          <name>d793ed79-daeb-43ad-813e-a0a33fb5cab0</name>
+          <entityField>syncIcon</entityField>
+        </neonTreeTableColumn>
         <neonTreeTableColumn>
           <name>860f55a7-8153-4744-b664-73016719cbe1</name>
           <entityField>BEGIN_TIME</entityField>
@@ -71,6 +77,22 @@
           <name>c3110972-795b-4293-b082-8f8bee1aa2ec</name>
           <entityField>STATUS_APPOINTMENT</entityField>
         </neonTreeTableColumn>
+        <neonTreeTableColumn>
+          <name>4dce0e15-4980-45fd-8783-a40a29c8370e</name>
+          <entityField>APPOINTMENT_BEGIN_TIME</entityField>
+        </neonTreeTableColumn>
+        <neonTreeTableColumn>
+          <name>1c2a3db8-370f-4dfe-84cf-c7a2282ad977</name>
+          <entityField>APPOINTMENT_END_TIME</entityField>
+        </neonTreeTableColumn>
+        <neonTreeTableColumn>
+          <name>6592f911-c5b0-4e83-8c13-9ede740c1ede</name>
+          <entityField>APPOINTMENT_STATUS</entityField>
+        </neonTreeTableColumn>
+        <neonTreeTableColumn>
+          <name>7b83c44e-631b-4b7b-aca1-70f24911f74d</name>
+          <entityField>APPOINTMENT_SUBJECT</entityField>
+        </neonTreeTableColumn>
       </columns>
     </treeTableViewTemplate>
   </children>
diff --git a/neonView/VisitPlanEntryPreview_view/VisitPlanEntryPreview_view.aod b/neonView/VisitPlanEntryPreview_view/VisitPlanEntryPreview_view.aod
index e2fd831a5b92ff7d9618b2b301dada6c12056bd9..0b2a8cbf5abc1af5306a0ca7d03a5dc2518e7a94 100644
--- a/neonView/VisitPlanEntryPreview_view/VisitPlanEntryPreview_view.aod
+++ b/neonView/VisitPlanEntryPreview_view/VisitPlanEntryPreview_view.aod
@@ -25,6 +25,10 @@
           <name>e8950f3a-edbc-4e30-8c01-aa546195317d</name>
           <entityField>CONTACT_ID</entityField>
         </entityFieldLink>
+        <entityFieldLink>
+          <name>ea7d538f-9758-4f02-9e39-1b18c6d69cf1</name>
+          <entityField>APPOINTMENT_ID</entityField>
+        </entityFieldLink>
         <entityFieldLink>
           <name>535ebb8b-20d5-43c0-84dd-c4494e6edad9</name>
           <entityField>ENTRYDATE</entityField>
diff --git a/process/Appointment_lib/process.js b/process/Appointment_lib/process.js
index db2af54d0851e8c93d6d63881f8b8310b336feac..309d0782cbe074611e4c1365caa043e2b9f5909e 100644
--- a/process/Appointment_lib/process.js
+++ b/process/Appointment_lib/process.js
@@ -1,3 +1,4 @@
+import("system.translate");
 import("system.vars");
 import("system.tools");
 import("Calendar_lib");
@@ -167,4 +168,39 @@ AppointmentUtils.setAppointmentLinkComponentState = function(pSysRecordstate, pA
         return neon.COMPONENTSTATE_EDITABLE
     else
         return neon.COMPONENTSTATE_DISABLED;
+}
+
+/*
+ * returns displayvalue from appointmentstatus
+ * 
+ * @param {String} pStatus statusvalue (CONFIRMED, BUSY, CANCELLED, OOF, FREE)
+ * 
+ * @return {String} status displayvalue 
+ **/
+AppointmentUtils.getAppointmentStatusDisplayValue = function(pStatus)
+{
+    var res = "";
+    
+    switch(pStatus)
+    {
+        case "CONFIRMED":
+        case "BUSY":
+            res = translate.text("Confirmed")
+            break;
+        case "CANCELLED":
+            res = translate.text("Cancelled")
+            break;
+        case "TENTATIVE":
+            res = translate.text("Tentative")
+            break;
+        case "OOF":
+            res = translate.text("OutOfOffice")
+            break;
+        case "FREE":
+            res = translate.text("Free")
+            break;
+        default:
+            break;
+    }
+    return res;
 }
\ No newline at end of file
diff --git a/process/VisitPlanning_lib/process.js b/process/VisitPlanning_lib/process.js
index 80ae9c5f42690d369575fbbc467eb1757f39dc29..ea5f378abb2edf4ad181da82abf6e9a34e42bcf6 100644
--- a/process/VisitPlanning_lib/process.js
+++ b/process/VisitPlanning_lib/process.js
@@ -1,3 +1,6 @@
+import("KeywordRegistry_basic");
+import("system.eMath");
+import("system.translate");
 import("Sql_lib");
 import("Employee_lib");
 import("system.datetime");
@@ -20,8 +23,7 @@ function VisitPlanningUtils() {}
  * 
  * @param {String} [pIsDayRoute] Opens the route only for one address, otherwise all of selected week and it's date
  * 
- * @return {void} {content:   base64-encoded CSV; 
- *                   filename:  filename}
+ * @return {void}
  * 
  */
 VisitPlanningUtils.openRoute = function (pIsDayRoute)
@@ -34,33 +36,33 @@ VisitPlanningUtils.openRoute = function (pIsDayRoute)
 
     //start homeaddress
     addressIdStart = newSelect("ADDRESSID")
-                .from("ADDRESS")
-                .where("ADDRESS.ADDR_TYPE", "HOMEADDR")
-                .and("ADDRESS.CONTACT_ID", user)
-                .cell();
+    .from("ADDRESS")
+    .where("ADDRESS.ADDR_TYPE", "HOMEADDR")
+    .and("ADDRESS.CONTACT_ID", user)
+    .cell();
 
     if(!addressIdStart)
     {
         //start orgaddress
         var orgID = newSelect("ORGANISATION_ID")
-                .from("CONTACT")
-                .where("CONTACT.CONTACTID", user)
-                .cell();
-
+        .from("CONTACT")
+        .where("CONTACT.CONTACTID", user)
+        .cell();
+    
         addressIdStart = newSelect("ADDRESS_ID")
-                                    .from("CONTACT")
-                                    .where("CONTACT.ORGANISATION_ID", orgID)
-                                    .and("CONTACT.PERSON_ID is null")
-                                    .cell();
+        .from("CONTACT")
+        .where("CONTACT.ORGANISATION_ID", orgID)
+        .and("CONTACT.PERSON_ID is null")
+        .cell();
     }
 
     var addressStart = "";
     if(addressIdStart)
     {
         addressStart = newSelect("ADDRESS, BUILDINGNO, ZIP, CITY, COUNTRY")
-                                    .from("ADDRESS")
-                                    .where("ADDRESS.ADDRESSID", addressIdStart)
-                                    .arrayRow();
+        .from("ADDRESS")
+        .where("ADDRESS.ADDRESSID", addressIdStart)
+        .arrayRow();
 
         visitAddresses.push(addressStart.join("+"));
     }
@@ -71,7 +73,7 @@ VisitPlanningUtils.openRoute = function (pIsDayRoute)
 
     var entrydate = selectionRowData[0]["ENTRYDATE"]
 
-    var entryid = vars.get("$param.Entries_param");
+        var entryid = vars.get("$param.Entries_param");
     
     var cond = newWhere("VISITPLANENTRY.VISITPLANEMPLOYEEWEEK_ID", entryid).and("VISITPLANENTRY.ENTRYDATE", entrydate)
     
@@ -79,24 +81,111 @@ VisitPlanningUtils.openRoute = function (pIsDayRoute)
     {
         cond = cond.and("VISITPLANENTRY.VISITPLANENTRYID", selectionRowData[0]["VISITPLANENTRYID"]);
     }
-    var childAddresses = newSelect("ADDRESS, BUILDINGNO, ZIP, CITY, COUNTRY")
-                                    .from("ADDRESS")
-                                    .leftJoin("VISITPLANENTRY", "ADDRESS.ADDRESSID = (select ADDRESS_ID from CONTACT where CONTACT.CONTACTID \n\
+        var childAddresses = newSelect("ADDRESS, BUILDINGNO, ZIP, CITY, COUNTRY")
+        .from("ADDRESS")
+        .leftJoin("VISITPLANENTRY", "ADDRESS.ADDRESSID = (select ADDRESS_ID from CONTACT where CONTACT.CONTACTID \n\
                                                 = VISITPLANENTRY.ORGANISATION_CONTACT_ID)")
                                     .where(cond)
                                     .and("VISITPLANENTRY.ENTRYDATE", entrydate)
-                                    .table();
+        .table();
 
 
-    for(let i = 0; i < childAddresses.length; i++)
-    {
-        visitAddresses.push(childAddresses[i].join("+"));
-    }
+        for(let i = 0; i < childAddresses.length; i++)
+        {
+            visitAddresses.push(childAddresses[i].join("+"));
+        }
 
-    visitAddresses.push(addressStart.join("+"));
+        visitAddresses.push(addressStart.join("+"));
 
 
     address = "https://www.google.com/maps/dir/" + visitAddresses.join("/");
 
     neon.openUrl(address, true);
 };
+
+/*
+ * returns the priority from visitrecommendation based on the due date
+ * 
+ * @param {Date} [pDueDate] Due date from Visitrecommendation
+ * 
+ * @return {String} Priority
+ * 
+ */
+VisitPlanningUtils.getPrioByDueDate = function(pDueDate)
+{
+    var prio = "";
+    var currentDate = datetime.date();
+    
+    if(pDueDate != "")
+    {
+        var dateDifference = pDueDate - currentDate;
+
+        if(dateDifference < 0)
+        {
+            prio = $KeywordRegistry.visitRecommendationPriority$critical();
+        }
+        else if(dateDifference < datetime.ONE_DAY * 3)
+        {
+            prio = $KeywordRegistry.visitRecommendationPriority$veryHigh();
+        }
+        else if(dateDifference < datetime.ONE_DAY * 7)
+        {
+            prio = $KeywordRegistry.visitRecommendationPriority$high();
+        }
+        else if(dateDifference < datetime.ONE_DAY * 14)
+        {
+            prio = $KeywordRegistry.visitRecommendationPriority$medium();
+        }
+        else
+        {
+            prio = $KeywordRegistry.visitRecommendationPriority$low();
+        }
+    }
+    
+    return prio;
+}
+
+/*
+ * checks if Frequency should be displayed Visitrecommendation Filterview.
+ * 
+ * It should be displayed if:
+ *      - No manual Recommendation exists
+ *      - It is already planned (Visitplanentry exists)
+ *      - If Visitplanentry is older than 7 days and no activity for the visit exists
+ *      
+ * @param {String} [pContactId] Contactid from Organisation or Person
+ * @param {String} [pPrioritySource] Priority from Visitrecommendation (Frequency or Manual)
+ * 
+ * @return {Boolean} true if Frequency should be displayed
+ * 
+ **/
+VisitPlanningUtils.checkIfFrequencyIsRecommendation = function(pContactId, pPrioritySource)
+{
+    var res = false;
+    var manualRecCount = newSelect("count(VISITRECOMMENDATIONID)")
+        .from("VISITRECOMMENDATION")
+        .where("VISITRECOMMENDATION.CONTACT_ID", pContactId)
+        .or("VISITRECOMMENDATION.CONTACT_PERSON_ID", pContactId)
+        .cell()
+        
+    var visitEntry = newSelect("count(VISITPLANENTRYID)")
+    .from("VISITPLANENTRY")
+    .where(newWhere("VISITPLANENTRY.CONTACT_ID", pContactId)
+        .or("VISITPLANENTRY.ORGANISATION_CONTACT_ID", pContactId))
+
+    var visitEntryExists = visitEntry.cell();
+
+    visitEntry = visitEntry.and(newWhere("VISITPLANENTRY.ENTRYDATE", eMath.subInt(vars.get("$sys.today"), datetime.ONE_DAY * 7), SqlBuilder.LESS_OR_EQUAL())
+        .and("VISITPLANENTRY.STATUS", $KeywordRegistry.visitPlanEntryStatus$Visitreportcreated(), SqlBuilder.NOT_EQUAL()))
+        .or("VISITPLANENTRY.STATUS", $KeywordRegistry.visitPlanEntryStatus$Visitreportcreated(), SqlBuilder.EQUAL()).cell()
+
+    if(pPrioritySource != $KeywordRegistry.visitRecommendationPrioSource$manual() && manualRecCount < 0) //if manual Record was created, visitfrequency is not relevant
+    {
+       //!visitEntryExists - if no visitplanentry for the organisation/person from recommendation was created -> show recommendation so it can be planned
+       if(visitEntryExists == 0 || visitEntry < 0)
+       {    
+           res = true;
+       }
+    }
+    return res;
+}