diff --git a/.liquibase/Data_alias/changelog.xml b/.liquibase/Data_alias/changelog.xml
index c46a164da2f3cc26f2336d2aba78a1d54067672e..7011168d6cefd0a8907ac29a9fc325ef7970ca1b 100644
--- a/.liquibase/Data_alias/changelog.xml
+++ b/.liquibase/Data_alias/changelog.xml
@@ -24,5 +24,5 @@
     <include relativeToChangelogFile="true" file="basic/2021.0.2/changelog.xml"/>
     
     <!--enable this only when you definetly want to overwrite the existing data with demo records:-->
-    <!--<include relativeToChangelogFile="true" file="basic/_demoData/changelog.xml" context="example"/>-->
+    <include relativeToChangelogFile="true" file="basic/_demoData/changelog.xml" context="example"/>
 </databaseChangeLog>
\ No newline at end of file
diff --git a/entity/Salesproject_entity/Salesproject_entity.aod b/entity/Salesproject_entity/Salesproject_entity.aod
index 9271fa197f2a2bbd5d6e13c38f944433293a2303..d567ac3a36efcd8d474b14981641eb0eda498497 100644
--- a/entity/Salesproject_entity/Salesproject_entity.aod
+++ b/entity/Salesproject_entity/Salesproject_entity.aod
@@ -1096,6 +1096,22 @@
           <filterConditionProcess>%aditoprj%/entity/Salesproject_entity/recordcontainers/db/filterextensions/favorite_filter/filterConditionProcess.js</filterConditionProcess>
           <filtertype>BASIC</filtertype>
         </filterExtension>
+        <filterExtension>
+          <name>Touchpoint_filterExtension</name>
+          <title>Touchpoint</title>
+          <contentType>TEXT</contentType>
+          <filterValuesProcess>%aditoprj%/entity/Salesproject_entity/recordcontainers/db/filterextensions/touchpoint_filterextension/filterValuesProcess.js</filterValuesProcess>
+          <filterConditionProcess>%aditoprj%/entity/Salesproject_entity/recordcontainers/db/filterextensions/touchpoint_filterextension/filterConditionProcess.js</filterConditionProcess>
+          <filtertype>BASIC</filtertype>
+        </filterExtension>
+        <filterExtension>
+          <name>Competitor_filterExtension</name>
+          <title>Competitor</title>
+          <contentType>TEXT</contentType>
+          <filterValuesProcess>%aditoprj%/entity/Salesproject_entity/recordcontainers/db/filterextensions/competitor_filterextension/filterValuesProcess.js</filterValuesProcess>
+          <filterConditionProcess>%aditoprj%/entity/Salesproject_entity/recordcontainers/db/filterextensions/competitor_filterextension/filterConditionProcess.js</filterConditionProcess>
+          <filtertype>BASIC</filtertype>
+        </filterExtension>
       </filterExtensions>
     </dbRecordContainer>
     <indexRecordContainer>
diff --git a/entity/Salesproject_entity/recordcontainers/db/filterextensions/competitor_filterextension/filterConditionProcess.js b/entity/Salesproject_entity/recordcontainers/db/filterextensions/competitor_filterextension/filterConditionProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..61aad6335617d06c23db12be6b2a690a5a5db5ba
--- /dev/null
+++ b/entity/Salesproject_entity/recordcontainers/db/filterextensions/competitor_filterextension/filterConditionProcess.js
@@ -0,0 +1,32 @@
+import("system.result");
+import("system.vars");
+import("Sql_lib");
+import("system.SQLTYPES");
+
+var localvalue = vars.get("$local.rawvalue");
+var subselect = newSelect("COMPETITION.OBJECT_ROWID")
+    .from("COMPETITION")
+    .where("COMPETITION.OBJECT_TYPE", "Salesproject")
+    .and("COMPETITION.CONTACT_ID", localvalue || "");
+var competitors = newSelect("count(COMPETITION.OBJECT_ROWID)")
+    .from("COMPETITION")
+    .where("COMPETITION.OBJECT_TYPE", "Salesproject")
+    .and("COMPETITION.OBJECT_ROWID = SALESPROJECT.SALESPROJECTID");
+
+var sql;
+switch(parseInt(vars.get("$local.operator")))
+{
+    case 1: // equal
+        sql = newWhere("SALESPROJECT.SALESPROJECTID", subselect, SqlBuilder.IN()).toString();
+        break;
+    case 2: // not equal
+        sql = newWhere("SALESPROJECT.SALESPROJECTID", subselect, SqlBuilder.NOT_IN()).toString();
+        break;
+    case 12: // empty
+        sql = newWhere(competitors, 0, SqlBuilder.EQUAL(), SQLTYPES.NUMERIC).toString();
+        break;
+    case 11: // not empty
+        sql = newWhere(competitors, 0, SqlBuilder.GREATER(), SQLTYPES.NUMERIC).toString();
+        break;
+}
+result.string(sql);
diff --git a/entity/Salesproject_entity/recordcontainers/db/filterextensions/competitor_filterextension/filterValuesProcess.js b/entity/Salesproject_entity/recordcontainers/db/filterextensions/competitor_filterextension/filterValuesProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..da7c6ab53f019279a547eceb717a2f49dc14a6a2
--- /dev/null
+++ b/entity/Salesproject_entity/recordcontainers/db/filterextensions/competitor_filterextension/filterValuesProcess.js
@@ -0,0 +1,11 @@
+import("system.result");
+import("Sql_lib");
+import("Organisation_lib");
+
+result.object(newSelect([
+    "CONTACT.CONTACTID",
+    "ORGANISATION.NAME"
+])
+.from("ORGANISATION")
+.join("CONTACT", newWhere("ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID"))
+.table());
diff --git a/entity/Salesproject_entity/recordcontainers/db/filterextensions/touchpoint_filterextension/filterConditionProcess.js b/entity/Salesproject_entity/recordcontainers/db/filterextensions/touchpoint_filterextension/filterConditionProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..9e06360e475c11bd6155eb6165edd58d915ddabe
--- /dev/null
+++ b/entity/Salesproject_entity/recordcontainers/db/filterextensions/touchpoint_filterextension/filterConditionProcess.js
@@ -0,0 +1,33 @@
+import("system.result");
+import("system.vars");
+import("Sql_lib");
+import("system.SQLTYPES");
+
+var localvalue = vars.get("$local.rawvalue");
+var subselect = newSelect("SALESPROJECT.SALESPROJECTID")
+    .from("SALESPROJECT")
+    .join("SALESPROJECT_TOUCHPOINT", newWhere(
+        "SALESPROJECT.SALESPROJECTID = SALESPROJECT_TOUCHPOINT.SALESPROJECT_ID"
+    ))
+    .where("SALESPROJECT_TOUCHPOINT.TOUCHPOINT", localvalue || ""); // wont be used if op = is null or is not null
+var touchpoints = newSelect("count(SALESPROJECT_TOUCHPOINT.SALESPROJECT_ID)")
+    .from("SALESPROJECT_TOUCHPOINT")
+    .where("SALESPROJECT.SALESPROJECTID = SALESPROJECT_TOUCHPOINT.SALESPROJECT_ID");
+
+var sql;
+switch(parseInt(vars.get("$local.operator")))
+{
+    case 1: // equal
+        sql = newWhere("SALESPROJECT.SALESPROJECTID", subselect, SqlBuilder.IN()).toString();
+        break;
+    case 2: // not equal
+        sql = newWhere("SALESPROJECT.SALESPROJECTID", subselect, SqlBuilder.NOT_IN()).toString();
+        break;
+    case 12: // empty
+        sql = newWhere(touchpoints, 0, SqlBuilder.EQUAL(), SQLTYPES.NUMERIC).toString();
+        break;
+    case 11: // not empty
+        sql = newWhere(touchpoints, 0, SqlBuilder.GREATER(), SQLTYPES.NUMERIC).toString();
+        break;
+}
+result.string(sql);
diff --git a/entity/Salesproject_entity/recordcontainers/db/filterextensions/touchpoint_filterextension/filterValuesProcess.js b/entity/Salesproject_entity/recordcontainers/db/filterextensions/touchpoint_filterextension/filterValuesProcess.js
new file mode 100644
index 0000000000000000000000000000000000000000..ef9d1d795beb1186682b10820e56882e21136072
--- /dev/null
+++ b/entity/Salesproject_entity/recordcontainers/db/filterextensions/touchpoint_filterextension/filterValuesProcess.js
@@ -0,0 +1,5 @@
+import("system.result");
+import("Keyword_lib");
+import("KeywordRegistry_basic");
+
+result.object(KeywordUtils.getEntryNamesAndIdsByContainer($KeywordRegistry.salesprojectSource()));