diff --git a/.liquibase/Data_alias/basic/2021.1.0/EwsContactSync/add_AB_SYNCCONTACT_updateContact.xml b/.liquibase/Data_alias/basic/2021.1.0/EwsContactSync/add_AB_SYNCCONTACT_updateContact.xml new file mode 100644 index 0000000000000000000000000000000000000000..57c13af651bd7b145f1040e5b15e4ebb53da5d1b --- /dev/null +++ b/.liquibase/Data_alias/basic/2021.1.0/EwsContactSync/add_AB_SYNCCONTACT_updateContact.xml @@ -0,0 +1,12 @@ +<?xml version="1.1" encoding="UTF-8" standalone="no"?> +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + <changeSet author="f.maier" id="0b7c88d9-30d6-4225-b734-3a4baa06b7fc"> + <addColumn tableName="AB_SYNCCONTACT"> + <column name="UPDATECONTACT" type="CHAR(1)"/> + </addColumn> + <createIndex indexName="IDX_AB_SYNCCONTACT_UNIQUEID" tableName="AB_SYNCCONTACT" unique="true"> + <column name="CONTACT_ID"/> + <column name="USER_ID"/> + </createIndex> + </changeSet> +</databaseChangeLog> \ No newline at end of file diff --git a/.liquibase/Data_alias/basic/2021.1.0/EwsContactSync/create_ewsInfoLog.xml b/.liquibase/Data_alias/basic/2021.1.0/EwsContactSync/create_ewsInfoLog.xml new file mode 100644 index 0000000000000000000000000000000000000000..1a2e61d3906dfe857ef27e219ff92974b29e4411 --- /dev/null +++ b/.liquibase/Data_alias/basic/2021.1.0/EwsContactSync/create_ewsInfoLog.xml @@ -0,0 +1,17 @@ +<?xml version="1.1" encoding="UTF-8" standalone="no"?> +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> + <changeSet author="f.maier" id="7eaaf765-cb1d-4060-978e-06966071d6fm"> + <createTable tableName="EWS_INFO_LOG"> + <column name="EWS_INFO_LOGID" type="CHAR(36)"> + <constraints primaryKey="true" primaryKeyName="PK_EWS_INFO_LOG_EWS_INFO_LOGID"/> + </column> + <column name="DATE_NEW" type="TIMESTAMP"/> + <column name="USER_ID" type="VARCHAR(63)"/> + <column name="TYPE" type="VARCHAR(50)"/> + <column name="INFO" type="VARCHAR(5000)"/> + <column name="PRIORITY" type="VARCHAR(50)"/> + </createTable> + </changeSet> +</databaseChangeLog> \ No newline at end of file diff --git a/.liquibase/Data_alias/basic/2021.1.0/changelog.xml b/.liquibase/Data_alias/basic/2021.1.0/changelog.xml index 0a7259a9b95118cb6870f11cf94d6f032d21cfbb..d23a18f8fb29173c0522892be410c03620a6c31d 100644 --- a/.liquibase/Data_alias/basic/2021.1.0/changelog.xml +++ b/.liquibase/Data_alias/basic/2021.1.0/changelog.xml @@ -7,6 +7,9 @@ <include relativeToChangelogFile="true" file="offerWorkflow/add_ab_keyword_entry_offerstatus.xml"/> <include relativeToChangelogFile="true" file="offerWorkflow/add_ab_keyword_entry_activityCategory.xml"/> <include relativeToChangelogFile="true" file="create_standardWorkflow.xml"/> + + <include relativeToChangelogFile="true" file="EwsContactSync/create_ewsInfoLog.xml"/> + <include relativeToChangelogFile="true" file="EwsContactSync/add_AB_SYNCCONTACT_updateContact.xml"/> <include relativeToChangelogFile="true" file="Advertising/changelog.xml"/> <include relativeToChangelogFile="true" file="Bulkmail/changelog.xml"/> <include relativeToChangelogFile="true" file="Addressvalidation/changelog.xml"/> diff --git a/aliasDefinition/Data_alias/Data_alias.aod b/aliasDefinition/Data_alias/Data_alias.aod index 5d1357c00cf29de9a3db3358b7494553f8a0b16f..feec25de65ce36341ba0f176987e4c67d325f38b 100644 --- a/aliasDefinition/Data_alias/Data_alias.aod +++ b/aliasDefinition/Data_alias/Data_alias.aod @@ -11153,15 +11153,17 @@ </entityFieldDb> <entityFieldDb> <name>EMPLOYEE_CONTACT_ID</name> + <dbName></dbName> + <primaryKey v="false" /> <columnType v="1" /> <size v="36" /> - <dependencies> - <entityDependency> - <name>6a1da471-b60b-40ae-a099-89f8835abd61</name> - <entityName>CONTACT</entityName> - <fieldName>CONTACTID</fieldName> - </entityDependency> - </dependencies> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> </entityFieldDb> <entityFieldDb> <name>DATE_EDIT</name> @@ -18695,7 +18697,7 @@ <idColumn>SYNCCONTACTID</idColumn> <idGeneratorType v="0" /> <idGeneratorInterval v="1" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/documentation.adoc</documentation> <title></title> <description></description> <auditSyncConfig> @@ -18717,7 +18719,7 @@ <notNull v="false" /> <isUnique v="false" /> <index v="false" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_edit/documentation.adoc</documentation> <title></title> <description></description> </entityFieldDb> @@ -18731,7 +18733,7 @@ <notNull v="false" /> <isUnique v="false" /> <index v="true" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/exchangeid/documentation.adoc</documentation> <title></title> <description></description> </entityFieldDb> @@ -18745,7 +18747,7 @@ <notNull v="false" /> <isUnique v="true" /> <index v="true" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/asys_favoriteid/documentation.adoc</documentation> <title></title> <description></description> </entityFieldDb> @@ -18759,7 +18761,7 @@ <notNull v="false" /> <isUnique v="false" /> <index v="true" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/user_id/documentation.adoc</documentation> <title></title> <description></description> </entityFieldDb> @@ -18773,7 +18775,7 @@ <notNull v="false" /> <isUnique v="false" /> <index v="true" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/contact_id/documentation.adoc</documentation> <title></title> <description></description> </entityFieldDb> @@ -18787,7 +18789,7 @@ <notNull v="false" /> <isUnique v="false" /> <index v="false" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_new/documentation.adoc</documentation> <title></title> <description></description> </entityFieldDb> @@ -18801,7 +18803,7 @@ <notNull v="true" /> <isUnique v="true" /> <index v="true" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/synccontactid/documentation.adoc</documentation> <title></title> <description></description> </entityFieldDb> @@ -18815,7 +18817,21 @@ <notNull v="false" /> <isUnique v="false" /> <index v="false" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_del/documentation.adoc</documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>UPDATECONTACT</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="1" /> + <size v="1" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/updatecontact/documentation.adoc</documentation> <title></title> <description></description> </entityFieldDb> @@ -21671,17 +21687,17 @@ </entityFields> </entityDb> <entityDb> - <name>ADVERTISING</name> + <name>EWS_INFO_LOG</name> <dbName></dbName> - <idColumn>ADVERTISINGID</idColumn> + <idColumn>EWS_INFO_LOGID</idColumn> <idGeneratorType v="0" /> <idGeneratorInterval v="1" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/documentation.adoc</documentation> <title></title> <description></description> <auditSyncConfig> <name>auditSyncConfig</name> - <auditMode v="2" /> + <auditMode v="0" /> <syncActive v="false" /> <syncComplete v="true" /> <syncDirection v="1" /> @@ -21689,7 +21705,7 @@ </auditSyncConfig> <entityFields> <entityFieldDb> - <name>ADVERTISINGID</name> + <name>EWS_INFO_LOGID</name> <dbName></dbName> <primaryKey v="true" /> <columnType v="1" /> @@ -21698,130 +21714,107 @@ <notNull v="true" /> <isUnique v="true" /> <index v="true" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/ews_info_logid/documentation.adoc</documentation> <title></title> <description></description> </entityFieldDb> <entityFieldDb> - <name>RESPONSIBLE_ID</name> + <name>USER_ID</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="1" /> - <size v="36" /> + <columnType v="12" /> + <size v="63" /> <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> <index v="true" /> - <documentation></documentation> - <title>Responsible</title> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/user_id/documentation.adoc</documentation> + <title></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/advertising/entityfields/responsible_id/customproperties/translate4log/property.js</property> - </customJDitoProperty> - </customProperties> </entityFieldDb> <entityFieldDb> - <name>CONTACT_ID</name> + <name>PRIORITY</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="1" /> - <size v="36" /> + <columnType v="12" /> + <size v="50" /> <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> <index v="true" /> - <documentation></documentation> - <title>Contact</title> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/priority/documentation.adoc</documentation> + <title></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/advertising/entityfields/contact_id/customproperties/translate4log/property.js</property> - </customJDitoProperty> - </customProperties> </entityFieldDb> <entityFieldDb> - <name>OBJECT_TYPE</name> + <name>DATE_NEW</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="12" /> - <size v="63" /> + <columnType v="93" /> + <size v="19" /> <scale v="0" /> - <notNull v="true" /> + <notNull v="false" /> <isUnique v="false" /> <index v="false" /> - <documentation></documentation> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/date_new/documentation.adoc</documentation> <title></title> <description></description> </entityFieldDb> <entityFieldDb> - <name>CURRENCY</name> + <name>INFO</name> <dbName></dbName> <primaryKey v="false" /> <columnType v="12" /> - <size v="36" /> + <size v="5000" /> <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> <index v="false" /> - <documentation></documentation> - <title>Currency</title> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/info/documentation.adoc</documentation> + <title></title> <description></description> - <customProperties> - <customBooleanProperty> - <name>log</name> - <global v="false" /> - <property v="true" /> - </customBooleanProperty> - </customProperties> </entityFieldDb> <entityFieldDb> - <name>STATUS</name> + <name>TYPE</name> <dbName></dbName> <primaryKey v="false" /> <columnType v="12" /> - <size v="36" /> + <size v="50" /> <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title>Status</title> + <index v="true" /> + <documentation>%aditoprj%/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/type/documentation.adoc</documentation> + <title></title> <description></description> - <customProperties> - <customBooleanProperty> - <name>log</name> - <global v="false" /> - <property v="true" /> - </customBooleanProperty> - <customStringProperty> - <name>keyword</name> - <global v="false" /> - <property>advertisingStatus</property> - </customStringProperty> - </customProperties> </entityFieldDb> + </entityFields> + </entityDb> + <entityDb> + <name>EMAIL_FILTER_HANDLING</name> + <dbName></dbName> + <idColumn>EMAIL_FILTER_HANDLINGID</idColumn> + <idGeneratorType v="0" /> + <idGeneratorInterval v="1" /> + <documentation></documentation> + <title></title> + <description></description> + <auditSyncConfig> + <name>auditSyncConfig</name> + <auditMode v="2" /> + <syncActive v="false" /> + <syncComplete v="true" /> + <syncDirection v="1" /> + <syncIds></syncIds> + </auditSyncConfig> + <entityFields> <entityFieldDb> - <name>DATE_EDIT</name> + <name>FILTER</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="93" /> - <size v="29" /> - <scale v="9" /> + <columnType v="-1" /> + <size v="2147483647" /> + <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> <index v="false" /> @@ -21830,12 +21823,12 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>DATE_NEW</name> + <name>WORKFLOWDEFINITION_KEY</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="93" /> - <size v="29" /> - <scale v="9" /> + <columnType v="12" /> + <size v="255" /> + <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> <index v="false" /> @@ -21844,11 +21837,11 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>USER_NEW</name> + <name>DESCRIPTION</name> <dbName></dbName> <primaryKey v="false" /> <columnType v="12" /> - <size v="50" /> + <size v="500" /> <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> @@ -21858,13 +21851,13 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>USER_EDIT</name> + <name>FILTER_TYPE</name> <dbName></dbName> <primaryKey v="false" /> <columnType v="12" /> - <size v="50" /> + <size v="36" /> <scale v="0" /> - <notNull v="false" /> + <notNull v="true" /> <isUnique v="false" /> <index v="false" /> <documentation></documentation> @@ -21872,59 +21865,39 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>OBJECT_ROWID</name> + <name>PRIORITY</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="1" /> - <size v="36" /> + <columnType v="4" /> + <size v="10" /> <scale v="0" /> <notNull v="true" /> <isUnique v="false" /> - <index v="true" /> + <index v="false" /> <documentation></documentation> <title></title> <description></description> </entityFieldDb> - </entityFields> - </entityDb> - <entityDb> - <name>ADVERTISINGITEM</name> - <dbName></dbName> - <idColumn>ADVERTISINGITEMID</idColumn> - <idGeneratorType v="0" /> - <idGeneratorInterval v="1" /> - <documentation></documentation> - <title></title> - <description></description> - <auditSyncConfig> - <name>auditSyncConfig</name> - <auditMode v="2" /> - <syncActive v="false" /> - <syncComplete v="true" /> - <syncDirection v="1" /> - <syncIds></syncIds> - </auditSyncConfig> - <entityFields> <entityFieldDb> - <name>ADVERTISINGITEMID</name> + <name>TITLE</name> <dbName></dbName> - <primaryKey v="true" /> - <columnType v="1" /> - <size v="36" /> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="250" /> <scale v="0" /> <notNull v="true" /> - <isUnique v="true" /> - <index v="true" /> + <isUnique v="false" /> + <index v="false" /> <documentation></documentation> <title></title> <description></description> </entityFieldDb> <entityFieldDb> - <name>UNIT</name> + <name>WORKFLOWSIGNAL_NAME</name> <dbName></dbName> <primaryKey v="false" /> <columnType v="12" /> - <size v="36" /> + <size v="250" /> <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> @@ -21934,33 +21907,26 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>PRICE</name> + <name>ISACTIVE</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="2" /> - <size v="14" /> - <scale v="2" /> - <notNull v="false" /> + <columnType v="-6" /> + <size v="3" /> + <scale v="0" /> + <notNull v="true" /> <isUnique v="false" /> <index v="false" /> <documentation></documentation> - <title>Price</title> + <title></title> <description></description> - <customProperties> - <customBooleanProperty> - <name>log</name> - <global v="false" /> - <property v="true" /> - </customBooleanProperty> - </customProperties> </entityFieldDb> <entityFieldDb> - <name>DATE_EDIT</name> + <name>ACTION_TYPE</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="93" /> - <size v="29" /> - <scale v="9" /> + <columnType v="12" /> + <size v="36" /> + <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> <index v="false" /> @@ -21969,17 +21935,297 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>QUANTITY</name> + <name>EMAIL_FILTER_HANDLINGID</name> <dbName></dbName> - <primaryKey v="false" /> - <columnType v="2" /> - <size v="14" /> - <scale v="2" /> - <notNull v="false" /> - <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title>Quantity</title> + <primaryKey v="true" /> + <columnType v="1" /> + <size v="36" /> + <scale v="0" /> + <notNull v="true" /> + <isUnique v="true" /> + <index v="true" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>ISFALLTHROUGH</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="1" /> + <size v="36" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="true" /> + <documentation></documentation> + <title>Responsible</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/advertising/entityfields/responsible_id/customproperties/translate4log/property.js</property> + </customJDitoProperty> + </customProperties> + </entityFieldDb> + <entityFieldDb> + <name>CONTACT_ID</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="1" /> + <size v="36" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="true" /> + <documentation></documentation> + <title>Contact</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/advertising/entityfields/contact_id/customproperties/translate4log/property.js</property> + </customJDitoProperty> + </customProperties> + </entityFieldDb> + <entityFieldDb> + <name>OBJECT_TYPE</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="63" /> + <scale v="0" /> + <notNull v="true" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>CURRENCY</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="36" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title>Currency</title> + <description></description> + <customProperties> + <customBooleanProperty> + <name>log</name> + <global v="false" /> + <property v="true" /> + </customBooleanProperty> + </customProperties> + </entityFieldDb> + <entityFieldDb> + <name>STATUS</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="36" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title>Status</title> + <description></description> + <customProperties> + <customBooleanProperty> + <name>log</name> + <global v="false" /> + <property v="true" /> + </customBooleanProperty> + <customStringProperty> + <name>keyword</name> + <global v="false" /> + <property>advertisingStatus</property> + </customStringProperty> + </customProperties> + </entityFieldDb> + <entityFieldDb> + <name>DATE_EDIT</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="93" /> + <size v="29" /> + <scale v="9" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>DATE_NEW</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="93" /> + <size v="29" /> + <scale v="9" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>USER_NEW</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="50" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>USER_EDIT</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="50" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>OBJECT_ROWID</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="1" /> + <size v="36" /> + <scale v="0" /> + <notNull v="true" /> + <isUnique v="false" /> + <index v="true" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + </entityFields> + </entityDb> + <entityDb> + <name>ADVERTISINGITEM</name> + <dbName></dbName> + <idColumn>ADVERTISINGITEMID</idColumn> + <idGeneratorType v="0" /> + <idGeneratorInterval v="1" /> + <documentation></documentation> + <title></title> + <description></description> + <auditSyncConfig> + <name>auditSyncConfig</name> + <auditMode v="2" /> + <syncActive v="false" /> + <syncComplete v="true" /> + <syncDirection v="1" /> + <syncIds></syncIds> + </auditSyncConfig> + <entityFields> + <entityFieldDb> + <name>ADVERTISINGITEMID</name> + <dbName></dbName> + <primaryKey v="true" /> + <columnType v="1" /> + <size v="36" /> + <scale v="0" /> + <notNull v="true" /> + <isUnique v="true" /> + <index v="true" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>UNIT</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="36" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>PRICE</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="2" /> + <size v="14" /> + <scale v="2" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title>Price</title> + <description></description> + <customProperties> + <customBooleanProperty> + <name>log</name> + <global v="false" /> + <property v="true" /> + </customBooleanProperty> + </customProperties> + </entityFieldDb> + <entityFieldDb> + <name>DATE_EDIT</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="93" /> + <size v="29" /> + <scale v="9" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>QUANTITY</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="2" /> + <size v="14" /> + <scale v="2" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title>Quantity</title> <description></description> <customProperties> <customBooleanProperty> @@ -22112,13 +22358,159 @@ <title></title> <description></description> </entityFieldDb> + <entityFieldDb> + <name>ADVERTISING_ID</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="1" /> + <size v="36" /> + <scale v="0" /> + <notNull v="true" /> + <isUnique v="false" /> + <index v="true" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> <entityFieldDb> <name>DATE_NEW</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="93" /> - <size v="29" /> - <scale v="9" /> + <columnType v="93" /> + <size v="29" /> + <scale v="9" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>USER_NEW</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="50" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>SENT</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="5" /> + <size v="5" /> + <scale v="0" /> + <notNull v="true" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + </entityFields> + </entityDb> + <entityDb> + <name>CURRENCYRATE</name> + <dbName></dbName> + <idColumn>CURRENCYRATEID</idColumn> + <idGeneratorType v="0" /> + <idGeneratorInterval v="1" /> + <documentation></documentation> + <title></title> + <description></description> + <auditSyncConfig> + <name>auditSyncConfig</name> + <auditMode v="0" /> + <syncActive v="false" /> + <syncComplete v="true" /> + <syncDirection v="1" /> + <syncIds></syncIds> + </auditSyncConfig> + <entityFields> + <entityFieldDb> + <name>CURRENCYRATEID</name> + <dbName></dbName> + <primaryKey v="true" /> + <columnType v="1" /> + <size v="36" /> + <scale v="0" /> + <notNull v="true" /> + <isUnique v="true" /> + <index v="true" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>TARGETCURRENCYISO</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="1" /> + <size v="3" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="true" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>DATE_EDIT</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="93" /> + <size v="19" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>CURRENCYRATE</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="6" /> + <size v="12" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>DATE_NEW</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="93" /> + <size v="19" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>SOURCECURRENCYISO</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="1" /> + <size v="3" /> + <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> <index v="false" /> @@ -22141,13 +22533,13 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>SENT</name> + <name>VALID_FROM</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="5" /> - <size v="5" /> + <columnType v="93" /> + <size v="19" /> <scale v="0" /> - <notNull v="true" /> + <notNull v="false" /> <isUnique v="false" /> <index v="false" /> <documentation></documentation> @@ -22155,15 +22547,15 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>ADVERTISING_ID</name> + <name>USER_EDIT</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="1" /> - <size v="36" /> + <columnType v="12" /> + <size v="50" /> <scale v="0" /> - <notNull v="true" /> + <notNull v="false" /> <isUnique v="false" /> - <index v="true" /> + <index v="false" /> <documentation></documentation> <title></title> <description></description> @@ -22171,9 +22563,9 @@ </entityFields> </entityDb> <entityDb> - <name>EMAIL_FILTER_HANDLING</name> + <name>ADVERTISING</name> <dbName></dbName> - <idColumn>EMAIL_FILTER_HANDLINGID</idColumn> + <idColumn>ADVERTISINGID</idColumn> <idGeneratorType v="0" /> <idGeneratorInterval v="1" /> <documentation></documentation> @@ -22189,11 +22581,11 @@ </auditSyncConfig> <entityFields> <entityFieldDb> - <name>FILTER</name> + <name>CURRENCY</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="-1" /> - <size v="2147483647" /> + <columnType v="12" /> + <size v="36" /> <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> @@ -22203,11 +22595,11 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>WORKFLOWDEFINITION_KEY</name> + <name>STATUS</name> <dbName></dbName> <primaryKey v="false" /> <columnType v="12" /> - <size v="255" /> + <size v="36" /> <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> @@ -22217,27 +22609,27 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>FILTER_TYPE</name> + <name>RESPONSIBLE_ID</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="12" /> + <columnType v="1" /> <size v="36" /> <scale v="0" /> - <notNull v="true" /> + <notNull v="false" /> <isUnique v="false" /> - <index v="false" /> + <index v="true" /> <documentation></documentation> <title></title> <description></description> </entityFieldDb> <entityFieldDb> - <name>TITLE</name> + <name>DATE_EDIT</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="12" /> - <size v="250" /> + <columnType v="93" /> + <size v="19" /> <scale v="0" /> - <notNull v="true" /> + <notNull v="false" /> <isUnique v="false" /> <index v="false" /> <documentation></documentation> @@ -22245,41 +22637,41 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>EMAIL_FILTER_HANDLINGID</name> + <name>CONTACT_ID</name> <dbName></dbName> - <primaryKey v="true" /> + <primaryKey v="false" /> <columnType v="1" /> <size v="36" /> <scale v="0" /> - <notNull v="true" /> - <isUnique v="true" /> + <notNull v="false" /> + <isUnique v="false" /> <index v="true" /> <documentation></documentation> <title></title> <description></description> </entityFieldDb> <entityFieldDb> - <name>PRIORITY</name> + <name>ADVERTISINGID</name> <dbName></dbName> - <primaryKey v="false" /> - <columnType v="4" /> - <size v="10" /> + <primaryKey v="true" /> + <columnType v="1" /> + <size v="36" /> <scale v="0" /> <notNull v="true" /> - <isUnique v="false" /> - <index v="false" /> + <isUnique v="true" /> + <index v="true" /> <documentation></documentation> <title></title> <description></description> </entityFieldDb> <entityFieldDb> - <name>ISACTIVE</name> + <name>DATE_NEW</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="-6" /> - <size v="3" /> + <columnType v="93" /> + <size v="19" /> <scale v="0" /> - <notNull v="true" /> + <notNull v="false" /> <isUnique v="false" /> <index v="false" /> <documentation></documentation> @@ -22287,13 +22679,13 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>DESCRIPTION</name> + <name>OBJECT_TYPE</name> <dbName></dbName> <primaryKey v="false" /> <columnType v="12" /> - <size v="500" /> + <size v="63" /> <scale v="0" /> - <notNull v="false" /> + <notNull v="true" /> <isUnique v="false" /> <index v="false" /> <documentation></documentation> @@ -22301,15 +22693,15 @@ <description></description> </entityFieldDb> <entityFieldDb> - <name>DATE_EDIT</name> + <name>ROW_ID</name> <dbName></dbName> <primaryKey v="false" /> - <columnType v="93" /> - <size v="19" /> + <columnType v="1" /> + <size v="36" /> <scale v="0" /> <notNull v="false" /> <isUnique v="false" /> - <index v="false" /> + <index v="true" /> <documentation></documentation> <title></title> <description></description> @@ -22342,20 +22734,6 @@ <title></title> <description></description> </entityFieldDb> - <entityFieldDb> - <name>DATE_NEW</name> - <dbName></dbName> - <primaryKey v="false" /> - <columnType v="93" /> - <size v="19" /> - <scale v="0" /> - <notNull v="false" /> - <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title></title> - <description></description> - </entityFieldDb> <entityFieldDb> <name>USER_NEW</name> <dbName></dbName> @@ -25710,152 +26088,6 @@ </entityFieldDb> </entityFields> </entityDb> - <entityDb> - <name>CURRENCYRATE</name> - <dbName></dbName> - <idColumn>CURRENCYRATEID</idColumn> - <idGeneratorType v="0" /> - <idGeneratorInterval v="1" /> - <documentation></documentation> - <title></title> - <description></description> - <auditSyncConfig> - <name>auditSyncConfig</name> - <auditMode v="0" /> - <syncActive v="false" /> - <syncComplete v="true" /> - <syncDirection v="1" /> - <syncIds></syncIds> - </auditSyncConfig> - <entityFields> - <entityFieldDb> - <name>CURRENCYRATEID</name> - <dbName></dbName> - <primaryKey v="true" /> - <columnType v="1" /> - <size v="36" /> - <scale v="0" /> - <notNull v="true" /> - <isUnique v="true" /> - <index v="true" /> - <documentation></documentation> - <title></title> - <description></description> - </entityFieldDb> - <entityFieldDb> - <name>TARGETCURRENCYISO</name> - <dbName></dbName> - <primaryKey v="false" /> - <columnType v="1" /> - <size v="3" /> - <scale v="0" /> - <notNull v="false" /> - <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title></title> - <description></description> - </entityFieldDb> - <entityFieldDb> - <name>DATE_EDIT</name> - <dbName></dbName> - <primaryKey v="false" /> - <columnType v="93" /> - <size v="19" /> - <scale v="0" /> - <notNull v="false" /> - <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title></title> - <description></description> - </entityFieldDb> - <entityFieldDb> - <name>CURRENCYRATE</name> - <dbName></dbName> - <primaryKey v="false" /> - <columnType v="6" /> - <size v="12" /> - <scale v="0" /> - <notNull v="false" /> - <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title></title> - <description></description> - </entityFieldDb> - <entityFieldDb> - <name>DATE_NEW</name> - <dbName></dbName> - <primaryKey v="false" /> - <columnType v="93" /> - <size v="19" /> - <scale v="0" /> - <notNull v="false" /> - <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title></title> - <description></description> - </entityFieldDb> - <entityFieldDb> - <name>SOURCECURRENCYISO</name> - <dbName></dbName> - <primaryKey v="false" /> - <columnType v="1" /> - <size v="3" /> - <scale v="0" /> - <notNull v="false" /> - <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title></title> - <description></description> - </entityFieldDb> - <entityFieldDb> - <name>USER_NEW</name> - <dbName></dbName> - <primaryKey v="false" /> - <columnType v="12" /> - <size v="50" /> - <scale v="0" /> - <notNull v="false" /> - <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title></title> - <description></description> - </entityFieldDb> - <entityFieldDb> - <name>VALID_FROM</name> - <dbName></dbName> - <primaryKey v="false" /> - <columnType v="93" /> - <size v="19" /> - <scale v="0" /> - <notNull v="false" /> - <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title></title> - <description></description> - </entityFieldDb> - <entityFieldDb> - <name>USER_EDIT</name> - <dbName></dbName> - <primaryKey v="false" /> - <columnType v="12" /> - <size v="50" /> - <scale v="0" /> - <notNull v="false" /> - <isUnique v="false" /> - <index v="false" /> - <documentation></documentation> - <title></title> - <description></description> - </entityFieldDb> - </entityFields> - </entityDb> <entityDb> <name>ASYS_NOTIFICATIONCONTENTS</name> <dbName></dbName> diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..8c23b48a98553e433a6b078a3751d94ae4caf64a --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/documentation.adoc @@ -0,0 +1,3 @@ += AB_SYNCCONTACT + +This table is used to store the information of which contacts should be synced with the ews exchange or which are already synced and which status they've got. diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/asys_favoriteid/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/asys_favoriteid/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..c8e26dc3d3d9622bdc4791b189fcc25474657d50 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/asys_favoriteid/documentation.adoc @@ -0,0 +1,6 @@ +== ASYS_FAVORITEID (FK) + +NOTE: This column will be obsolete in the future due to the refactoring of the contactsynchronisation and will be removed! + +This column is used to store the reference between the ab_synccontact table and the favorite tags + diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/contact_id/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/contact_id/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..fca837c92ef04555c5affeaef5e412601849a759 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/contact_id/documentation.adoc @@ -0,0 +1,3 @@ +== CONTACT_ID (FK) + +The CONTACT_ID shows which Person or Organisation is synced. It's also used to get the relevant data like phonenumber and name diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_del/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_del/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..d252bae418befb749581d8d0a67bb13b244dd728 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_del/documentation.adoc @@ -0,0 +1,3 @@ +== DATE_DEL + +Marks an entry for Deletion, the marked dataset will be removed from exchange with the next run of the synchronisation process \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_edit/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_edit/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..3a27140bf089eda2256444e90918c9f6a1d71462 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_edit/documentation.adoc @@ -0,0 +1,3 @@ +== DATE_EDIT + +This column represents the editing date of a dataset which is marked for the synchronization with exchange \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_new/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_new/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..005871702a8f9e04370adbd767058cd7084c8af0 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/date_new/documentation.adoc @@ -0,0 +1,3 @@ +== DATE_NEW + +The creation date of synchronization entry. The date which symbolize when a dataset was marked for the synchronization. \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/exchangeid/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/exchangeid/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..f9f743c5a8f81f088a29ac80d7393e9747e7d441 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/exchangeid/documentation.adoc @@ -0,0 +1,4 @@ +== EXCHANGEID + +The unique exchangeId of a dataset, with this Id update statements can be made to the synced dataset in exchange. +This column can also be null when a dataset is not synchronized with exchange yet. diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/synccontactid/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/synccontactid/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..447bd50ed1db5b3b06d28adfb31d1f21dee2622a --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/synccontactid/documentation.adoc @@ -0,0 +1,3 @@ +== SYNCCONTACTID (PK) + +The primary key of the ab_synccontact table. \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/updatecontact/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/updatecontact/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..8a31a73adfa74887e2e6e942c1913ec93059217c --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/updatecontact/documentation.adoc @@ -0,0 +1,5 @@ +== UPDATECONTACT + +This column is used to determine those datasets which should be updated in exchange. +1 = marked for update +0 = already up to date \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/user_id/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/user_id/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..a896d51a6468b297a6b4c65cedcaacb8fc56d6f9 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ab_synccontact/entityfields/user_id/documentation.adoc @@ -0,0 +1,3 @@ +== USER_ID (FK) + +Represents the USERID of the user which marked a dataset for the synchronisation \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..6fe53dd0fb3b61ec8b138f72cb253d0336703e9d --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/documentation.adoc @@ -0,0 +1,3 @@ +== EWS_INFO_LOG + +The EWS_INFO_LOG Table contains the log of the two synchronization processes \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/date_new/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/date_new/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..c27a8f0d9ced5b85988b48a0f8dec082304d12e0 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/date_new/documentation.adoc @@ -0,0 +1,3 @@ +== DATE_NEW + +Contains the timestamp of the creation date of the log \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/ews_info_logid/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/ews_info_logid/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..f5be62ffc01e2568c463594e430d2a76b9aba0f7 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/ews_info_logid/documentation.adoc @@ -0,0 +1,3 @@ +== EWS_INFO_LOGID (PK) + +The primary key of the ews_info table \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/info/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/info/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..9eaf13f1b38c34108037b555ba0c67863262ba72 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/info/documentation.adoc @@ -0,0 +1,3 @@ +== INFO + +Contains the logged info of the process runs. For example a throwed errormessage or a successful information \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/priority/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/priority/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..9159f01df52e9e13ba1190a67116aca99526aa64 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/priority/documentation.adoc @@ -0,0 +1,3 @@ +== PRIORITY + +This column contains the priority of the logged information. \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/type/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/type/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..d2622e9ce1cdda75b8e5d24ac8f7ea89b7513268 --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/type/documentation.adoc @@ -0,0 +1,3 @@ +== TYPE + +Contains the name of the exchangesycnhronization process which logged the information. \ No newline at end of file diff --git a/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/user_id/documentation.adoc b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/user_id/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..edd222f75a75946e999f28903e76e0429807727d --- /dev/null +++ b/aliasDefinition/Data_alias/aliasdefinitionsub/entitygroup/entities/ews_info_log/entityfields/user_id/documentation.adoc @@ -0,0 +1,3 @@ +== USER_ID + +Contains the userlogin for which an error was thrown \ No newline at end of file diff --git a/aliasDefinition/Data_alias_noAudit/Data_alias_noAudit.aod b/aliasDefinition/Data_alias_noAudit/Data_alias_noAudit.aod index b176bfca4ed5a0da589782c6351932481ab94639..b3519c357f472cb7e6708fa5e34c80e7d237ab3a 100644 --- a/aliasDefinition/Data_alias_noAudit/Data_alias_noAudit.aod +++ b/aliasDefinition/Data_alias_noAudit/Data_alias_noAudit.aod @@ -1195,6 +1195,20 @@ <title></title> <description></description> </entityFieldDb> + <entityFieldDb> + <name>UPDATECONTACT</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="1" /> + <size v="1" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> </entityFields> </entityDb> <entityDb> @@ -19471,6 +19485,110 @@ </entityFieldDb> </entityFields> </entityDb> + <entityDb> + <name>EWS_INFO_LOG</name> + <dbName></dbName> + <idColumn>EWS_INFO_LOGID</idColumn> + <idGeneratorType v="0" /> + <idGeneratorInterval v="1" /> + <documentation></documentation> + <title></title> + <description></description> + <auditSyncConfig> + <name>auditSyncConfig</name> + <auditMode v="0" /> + <syncActive v="false" /> + <syncComplete v="true" /> + <syncDirection v="1" /> + <syncIds></syncIds> + </auditSyncConfig> + <entityFields> + <entityFieldDb> + <name>EWS_INFO_LOGID</name> + <dbName></dbName> + <primaryKey v="true" /> + <columnType v="1" /> + <size v="36" /> + <scale v="0" /> + <notNull v="true" /> + <isUnique v="true" /> + <index v="true" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>USER_ID</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="63" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>PRIORITY</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="50" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>DATE_NEW</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="93" /> + <size v="19" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>INFO</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="5000" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + <entityFieldDb> + <name>TYPE</name> + <dbName></dbName> + <primaryKey v="false" /> + <columnType v="12" /> + <size v="50" /> + <scale v="0" /> + <notNull v="false" /> + <isUnique v="false" /> + <index v="false" /> + <documentation></documentation> + <title></title> + <description></description> + </entityFieldDb> + </entityFields> + </entityDb> </entities> </entityGroup> </aliasDefDb> diff --git a/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod b/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod index 6163debccb9b8f4f6450c1b8709e0bdc84c7deec..12f0de3b5ea54cda86dfa9305fccdabc730ae3e0 100644 --- a/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod +++ b/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod @@ -38,6 +38,10 @@ <name>Task</name> <kind v="10077" /> </entityNode> + <entityNode> + <name>SearchSync</name> + <kind v="10077" /> + </entityNode> </childNodes> </entityNode> </childNodes> @@ -460,6 +464,10 @@ <name>Checklist</name> <kind v="10077" /> </entityNode> + <entityNode> + <name>EWSSyncDashboard</name> + <kind v="10090" /> + </entityNode> <entityNode> <name>TopicTree</name> <kind v="10077" /> diff --git a/entity/Organisation_entity/Organisation_entity.aod b/entity/Organisation_entity/Organisation_entity.aod index 4adaa3fc0706ed2f5bec3d301504673f10e70b69..72cb6cdb2bf27b4774d18628cdb7caa3f8b578f0 100644 --- a/entity/Organisation_entity/Organisation_entity.aod +++ b/entity/Organisation_entity/Organisation_entity.aod @@ -1349,6 +1349,10 @@ </entityParameter> </children> </entityConsumer> + <entityParameter> + <name>SearchSyncCondition_param</name> + <expose v="true" /> + </entityParameter> <entityConsumer> <name>Campaigns</name> <dependency> diff --git a/entity/Organisation_entity/initFilterProcess.js b/entity/Organisation_entity/initFilterProcess.js index afecc1ede02d6f412681545610696b1efa17dc90..0d63b18bcadfa767381a1635111687cc5cd9e53f 100644 --- a/entity/Organisation_entity/initFilterProcess.js +++ b/entity/Organisation_entity/initFilterProcess.js @@ -5,7 +5,13 @@ import("KeywordRegistry_basic"); import("system.result"); var filter = vars.get("$param.FilterPreSet_param"); -if(!filter && vars.get("$sys.presentationmode") === neon.CONTEXT_PRESENTATIONMODE_FILTER) +var searchSyncCond = vars.get("$param.SearchSyncCondition_param"); + +if(searchSyncCond) +{ + filter = searchSyncCond; +} +else if(!filter && vars.get("$sys.presentationmode") === neon.CONTEXT_PRESENTATIONMODE_FILTER) { var statusInactive = $KeywordRegistry.contactStatus$inactive(); filter = JSON.stringify({ @@ -21,6 +27,7 @@ if(!filter && vars.get("$sys.presentationmode") === neon.CONTEXT_PRESENTATIONMOD }] }); } + if(filter) { result.string(filter); diff --git a/entity/Person_entity/Person_entity.aod b/entity/Person_entity/Person_entity.aod index 4d6defb5c9288fbe7cee8a38b93e55aab829977d..5668029cc950db0f04026a5a0abf6b8ce60676f4 100644 --- a/entity/Person_entity/Person_entity.aod +++ b/entity/Person_entity/Person_entity.aod @@ -1153,16 +1153,18 @@ <entityActionField> <name>addToContactSync</name> <title>add Contact to Sync</title> + <description>Old contact Sync function</description> <onActionProcess>%aditoprj%/entity/Person_entity/entityfields/filterviewactiongroup/children/addtocontactsync/onActionProcess.js</onActionProcess> <iconId>NEON:RECURRING_APPOINTMENT</iconId> - <state>EDITABLE</state> + <state>INVISIBLE</state> </entityActionField> <entityActionField> <name>removeFromContactSync</name> <title>remove Contact from Sync</title> + <description>Old contact Sync function</description> <onActionProcess>%aditoprj%/entity/Person_entity/entityfields/filterviewactiongroup/children/removefromcontactsync/onActionProcess.js</onActionProcess> <iconId>NEON:RECURRING_APPOINTMENT_MOVED</iconId> - <state>AUTO</state> + <state>INVISIBLE</state> </entityActionField> <entityActionField> <name>addAttributeToSelection</name> @@ -1304,6 +1306,10 @@ </entityParameter> </children> </entityConsumer> + <entityParameter> + <name>SearchSyncCondition_param</name> + <expose v="true" /> + </entityParameter> <entityConsumer> <name>Interests</name> <description>Used for the filterExtension "InterestLink_filter"</description> diff --git a/entity/Person_entity/initFilterProcess.js b/entity/Person_entity/initFilterProcess.js index afecc1ede02d6f412681545610696b1efa17dc90..d7dedeb79a5dd69c1e835cf2ccd96ecd6e730f07 100644 --- a/entity/Person_entity/initFilterProcess.js +++ b/entity/Person_entity/initFilterProcess.js @@ -5,7 +5,13 @@ import("KeywordRegistry_basic"); import("system.result"); var filter = vars.get("$param.FilterPreSet_param"); -if(!filter && vars.get("$sys.presentationmode") === neon.CONTEXT_PRESENTATIONMODE_FILTER) +var searchSyncCond = vars.get("$param.SearchSyncCondition_param"); + +if(searchSyncCond) +{ + filter = searchSyncCond; +} +else if(!filter && vars.get("$sys.presentationmode") === neon.CONTEXT_PRESENTATIONMODE_FILTER) { var statusInactive = $KeywordRegistry.contactStatus$inactive(); filter = JSON.stringify({ diff --git a/entity/SearchSync_entity/SearchSync_entity.aod b/entity/SearchSync_entity/SearchSync_entity.aod new file mode 100644 index 0000000000000000000000000000000000000000..e4b7a24f5b327d133960dffec1ec90b33ab10cc3 --- /dev/null +++ b/entity/SearchSync_entity/SearchSync_entity.aod @@ -0,0 +1,163 @@ +<?xml version="1.0" encoding="UTF-8"?> +<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.22" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.22"> + <name>SearchSync_entity</name> + <title>Contact synchronisation</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <grantDelete v="false" /> + <iconId>VAADIN:SEARCH</iconId> + <titlePlural>Contact synchronisations</titlePlural> + <recordContainer>db</recordContainer> + <entityFields> + <entityProvider> + <name>#PROVIDER</name> + </entityProvider> + <entityField> + <name>DATE_EDIT</name> + <contentType>DATE</contentType> + </entityField> + <entityField> + <name>DATE_NEW</name> + <title>Date</title> + <contentType>DATE</contentType> + </entityField> + <entityField> + <name>ID</name> + <title>ID</title> + </entityField> + <entityField> + <name>NAME</name> + <title>User</title> + </entityField> + <entityField> + <name>GROUPID</name> + <title>Type</title> + <groupable v="true" /> + </entityField> + <entityField> + <name>PROPKEY</name> + <title>Propkey</title> + </entityField> + <entityField> + <name>PROPVAL</name> + </entityField> + <entityField> + <name>PROPVAL_CLOB</name> + <contentType>LONG_TEXT</contentType> + </entityField> + <entityField> + <name>title</name> + <title>Title</title> + <valueProcess>%aditoprj%/entity/SearchSync_entity/entityfields/title/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>information</name> + <title>Information</title> + <displayValueProcess>%aditoprj%/entity/SearchSync_entity/entityfields/information/displayValueProcess.js</displayValueProcess> + </entityField> + <entityProvider> + <name>#PROVIDER_AGGREGATES</name> + <useAggregates v="true" /> + </entityProvider> + <entityField> + <name>picture</name> + <contentType>IMAGE</contentType> + </entityField> + <entityActionGroup> + <name>syncEntryGroup</name> + <children> + <entityActionField> + <name>addSyncEntry</name> + <title>Add to synchronisation</title> + <onActionProcess>%aditoprj%/entity/SearchSync_entity/entityfields/syncentrygroup/children/addsyncentry/onActionProcess.js</onActionProcess> + <selectionType>MULTI</selectionType> + <iconId>NEON:RECURRING_APPOINTMENT</iconId> + <tooltip>Add to synchronisation</tooltip> + </entityActionField> + <entityActionField> + <name>removeSyncEntry</name> + <title>Remove from synchronization</title> + <onActionProcess>%aditoprj%/entity/SearchSync_entity/entityfields/syncentrygroup/children/removesyncentry/onActionProcess.js</onActionProcess> + <selectionType>MULTI</selectionType> + <iconId>NEON:RECURRING_APPOINTMENT_MOVED</iconId> + <tooltip>Remove from synchronization</tooltip> + </entityActionField> + </children> + </entityActionGroup> + <entityField> + <name>synchronized</name> + <title>Synchronisation status</title> + <contentType>IMAGE</contentType> + </entityField> + </entityFields> + <recordContainers> + <dbRecordContainer> + <name>db</name> + <isPageable v="false" /> + <conditionProcess>%aditoprj%/entity/SearchSync_entity/recordcontainers/db/conditionProcess.js</conditionProcess> + <alias>_____SYSTEMALIAS</alias> + <recordFieldMappings> + <dbRecordFieldMapping> + <name>DATE_EDIT.value</name> + <recordfield>ASYS_USERS.DATE_EDIT</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>DATE_NEW.value</name> + <recordfield>ASYS_USERS.DATE_NEW</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>GROUPID.value</name> + <recordfield>ASYS_USERS.GROUPID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>ID.value</name> + <recordfield>ASYS_USERS.ID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>NAME.value</name> + <recordfield>ASYS_USERS.NAME</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>PROPKEY.value</name> + <recordfield>ASYS_USERS.PROPKEY</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>PROPVAL_CLOB.value</name> + <recordfield>ASYS_USERS.PROPVAL_CLOB</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>PROPVAL.value</name> + <recordfield>ASYS_USERS.PROPVAL</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>title.value</name> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>picture.value</name> + <expression>%aditoprj%/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/picture.value/expression.js</expression> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>GROUPID.displayValue</name> + <expression>%aditoprj%/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/groupid.displayvalue/expression.js</expression> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>synchronized.value</name> + <expression>%aditoprj%/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/synchronized.value/expression.js</expression> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>information.value</name> + <expression>%aditoprj%/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/information.value/expression.js</expression> + </dbRecordFieldMapping> + </recordFieldMappings> + <linkInformation> + <linkInformation> + <name>800c044a-ed13-45fe-b416-dd0028e941ca</name> + <tableName>ASYS_USERS</tableName> + <primaryKey>ID</primaryKey> + <isUIDTable v="true" /> + <readonly v="false" /> + </linkInformation> + </linkInformation> + </dbRecordContainer> + </recordContainers> +</entity> diff --git a/entity/SearchSync_entity/entityfields/information/displayValueProcess.js b/entity/SearchSync_entity/entityfields/information/displayValueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..5c8bd05ccc7dd473aaef7c2669bd960bc086106a --- /dev/null +++ b/entity/SearchSync_entity/entityfields/information/displayValueProcess.js @@ -0,0 +1,8 @@ +import("EwsSyncContact_lib"); +import("system.project"); +import("system.translate"); +import("system.result"); +import("system.vars"); + +var res = vars.get("$field.information"); +result.string(translate.withArguments(res, [project.getPreferenceValue("custom.ews.syncsize", EwsClientSyncUtils.getMaxSyncSize())])); diff --git a/entity/SearchSync_entity/entityfields/syncentrygroup/children/addsyncentry/onActionProcess.js b/entity/SearchSync_entity/entityfields/syncentrygroup/children/addsyncentry/onActionProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..315554decad4a4796482f964c5a64a1f7fc085ed --- /dev/null +++ b/entity/SearchSync_entity/entityfields/syncentrygroup/children/addsyncentry/onActionProcess.js @@ -0,0 +1,68 @@ +import("system.neon"); +import("system.project"); +import("system.result"); +import("system.logging"); +import("EwsSyncContact_lib"); +import("system.util"); +import("system.db"); +import("system.tools"); +import("Sql_lib"); +import("system.vars"); + +var selectedRows = vars.get("$sys.selection"); +var maxSyncsize = project.getPreferenceValue("custom.ews.syncsize", EwsClientSyncUtils.getMaxSyncSize()); +var columns = ["ID", "GROUPID", "NAME", "PROPKEY", "PROPVAL", "DATE_NEW"]; +var dateNow = vars.get("$sys.date"); + +var asysUsersData = newSelect("ASYS_USERS.GROUPID, ASYS_USERS.NAME, ASYS_USERS.ID, ASYS_USERS.PROPVAL_CLOB") +.from("ASYS_USERS") +.leftJoin("ASYS_USERS", newWhere("innerU.PROPVAL = ASYS_USERS.ID").and(["ASYS_USERS", "PROPKEY", "innerU"], "SearchSync"), "innerU") +.where("innerU.ID is null") +.and("ASYS_USERS.ID", selectedRows, SqlBuilder.IN()) +.table();//left as sql due to performance + +asysUsersData.forEach(function ([groupId, name, id, propvalClob]) +{ + var syncId = util.getNewUUID(); + var values = [syncId, groupId, name, "SearchSync", id, dateNow]; + + db.insertData("ASYS_USERS", columns, null, values); + + groupId = groupId.substring(7, groupId.length - 6); + var search = JSON.parse(propvalClob)["search"]; // filterpart of the JSON + var whereCond = db.toFilterCondition(JSON.stringify(search), groupId); + + //-------------------------------------------------------------------------- + + var sqlSyncSizeString = newSelect("distinct count(CONTACTID)", "Data_alias"); + + if(groupId == 'Person_entity') + { + sqlSyncSizeString.from("CONTACT") + .join("PERSON", "CONTACT.PERSON_ID = PERSON.PERSONID") + .join("ORGANISATION", "ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID") + .leftJoin("ADDRESS", "ADDRESS.ADDRESSID = CONTACT.ADDRESS_ID") + } + else + { + sqlSyncSizeString.from("CONTACT") + .join("ORGANISATION", "ORGANISATIONID = ORGANISATION_ID and PERSON_ID is null and CONTACTID != '0'") + .leftJoin("ADDRESS", "ADDRESS.ADDRESSID = CONTACT.ADDRESS_ID"); + } + //from organisation or from person + + if(whereCond) + { + sqlSyncSizeString.where(whereCond); + } + + var syncsize = sqlSyncSizeString.cell(); + + if(syncsize > maxSyncsize) + { + db.updateData("ASYS_USERS", ["PROPVAL_CLOB"], null, + ["Search greater %0, sync. not possible"], newWhere("ASYS_USERS.ID", syncId), SqlUtils.getBinariesAlias()); + } +}); + +neon.refreshAll(); \ No newline at end of file diff --git a/entity/SearchSync_entity/entityfields/syncentrygroup/children/removesyncentry/onActionProcess.js b/entity/SearchSync_entity/entityfields/syncentrygroup/children/removesyncentry/onActionProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..712f02e029d747afeeb158af07488371a91e4595 --- /dev/null +++ b/entity/SearchSync_entity/entityfields/syncentrygroup/children/removesyncentry/onActionProcess.js @@ -0,0 +1,14 @@ +import("system.neon"); +import("Employee_lib"); +import("system.tools"); +import("system.vars"); +import("Sql_lib"); + +var userId = EmployeeUtils.getCurrentUserId(); +var selectedRows = vars.get("$sys.selection"); + +newWhereIfSet("ASYS_USERS.PROPKEY","SearchSync") + .andIfSet("ASYS_USERS.PROPVAL", selectedRows, SqlBuilder.IN()) + .deleteData(); + +neon.refreshAll(); \ No newline at end of file diff --git a/entity/SearchSync_entity/entityfields/title/valueProcess.js b/entity/SearchSync_entity/entityfields/title/valueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..c69b810ddc42eefa10989c965e731d673e864033 --- /dev/null +++ b/entity/SearchSync_entity/entityfields/title/valueProcess.js @@ -0,0 +1,9 @@ +import("system.result"); +import("system.vars"); + +var obj = vars.getString("$field.PROPVAL_CLOB"); + +if(obj)//parse title from filter +{ + result.string(JSON.parse(obj).title); +} diff --git a/entity/SearchSync_entity/recordcontainers/db/conditionProcess.js b/entity/SearchSync_entity/recordcontainers/db/conditionProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..9e28fc745a6ae838030d5e9873338ea11218a16b --- /dev/null +++ b/entity/SearchSync_entity/recordcontainers/db/conditionProcess.js @@ -0,0 +1,14 @@ +import("system.logging"); +import("Employee_lib"); +import("system.result"); +import("Sql_lib"); +import("system.tools"); + +var userId = EmployeeUtils.getCurrentUserId(); + +var cond = newWhereIfSet("ASYS_USERS.NAME", userId) + .and(newWhereIfSet("ASYS_USERS.PROPKEY", "#FILTER:Organisation_entity.SAVED:%", SqlBuilder.LIKE()) + .or("ASYS_USERS.PROPKEY", "#FILTER:Person_entity.SAVED:%", SqlBuilder.LIKE())) + .and(newWhereIfSet("ASYS_USERS.PROPKEY != 'SearchSync'")); +logging.log(cond.toString()); +result.string(cond.toString()); diff --git a/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/groupid.displayvalue/expression.js b/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/groupid.displayvalue/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..2ea10c4d2f844cf9c8a26e81aaea466af1bbd541 --- /dev/null +++ b/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/groupid.displayvalue/expression.js @@ -0,0 +1,6 @@ +import("Sql_lib"); +import("system.translate"); +import("system.result"); + +result.string(SqlBuilder.caseWhen(newWhere("ASYS_USERS.GROUPID", "FILTER:Organisation_entity.SAVED")) +.thenString(translate.text("Organisation")).elseString(translate.text("Contact")).toString()); diff --git a/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/information.value/expression.js b/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/information.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..e08e3475d9f4613a54b7cb39c9f09770c11bbbc2 --- /dev/null +++ b/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/information.value/expression.js @@ -0,0 +1,7 @@ +import("Sql_lib"); +import("system.result"); + +result.string(newSelect("innerAsysUsers.PROPVAL_CLOB") +.from("ASYS_USERS", "innerAsysUsers") +.where("innerAsysUsers.PROPVAL = ASYS_USERS.ID") +.and(["ASYS_USERS", "PROPKEY", "innerAsysUsers"], "SearchSync")); diff --git a/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/picture.value/expression.js b/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/picture.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..79f1284b1123373cca50ba62adca6329c6150058 --- /dev/null +++ b/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/picture.value/expression.js @@ -0,0 +1,6 @@ +import("Sql_lib"); +import("system.vars"); +import("system.result"); + +var sqlMask = new SqlMaskingUtils(SqlUtils.getSystemAlias()); +result.string(sqlMask.concatenate(["'TEXT:'", "ASYS_USERS.GROUPID"])); diff --git a/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/synchronized.value/expression.js b/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/synchronized.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..d19036eb77e4417a0bc411d353cd1cf23f80e0cc --- /dev/null +++ b/entity/SearchSync_entity/recordcontainers/db/recordfieldmappings/synchronized.value/expression.js @@ -0,0 +1,15 @@ +import("Sql_lib"); +import("system.result"); +import("system.SQLTYPES"); + +var syncronizedIcon = SqlBuilder.caseWhen( + new SqlBuilder() + .selectCount("innerAsysUsers.ID") + .from("ASYS_USERS", "innerAsysUsers") + .where("innerAsysUsers.PROPVAL = ASYS_USERS.ID") + .and(["ASYS_USERS", "PROPKEY", "innerAsysUsers"], "SearchSync"), + 0, SqlBuilder.GREATER(), SQLTYPES.INTEGER) + .thenString("NEON:RECURRING_APPOINTMENT") + .elseString("NEON:RECURRING_APPOINTMENT_MOVED"); + +result.string(syncronizedIcon.toString()); \ No newline at end of file diff --git a/entity/Synccontact_entity/Synccontact_entity.aod b/entity/Synccontact_entity/Synccontact_entity.aod new file mode 100644 index 0000000000000000000000000000000000000000..889389fbddbbc5ce5f69f7546c22a4a60b8cfdc8 --- /dev/null +++ b/entity/Synccontact_entity/Synccontact_entity.aod @@ -0,0 +1,316 @@ +<?xml version="1.0" encoding="UTF-8"?> +<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.22" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.22"> + <name>Synccontact_entity</name> + <title>Dataset in Outlook</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <icon>VAADIN:FILE_REFRESH</icon> + <grantCreate v="false" /> + <grantUpdate v="false" /> + <grantDelete v="false" /> + <titlePlural>Datasets in Outlook</titlePlural> + <recordContainer>db</recordContainer> + <entityFields> + <entityProvider> + <name>#PROVIDER</name> + <targetContextField>TARGETCONTEXT</targetContextField> + <targetIdField>CONTACT_ID</targetIdField> + </entityProvider> + <entityProvider> + <name>#PROVIDER_AGGREGATES</name> + <useAggregates v="true" /> + </entityProvider> + <entityField> + <name>USER_ID</name> + <title>User</title> + </entityField> + <entityField> + <name>CONTACT_ID</name> + <title>Contact</title> + <consumer>AnyContacts</consumer> + <linkedContextProcess>%aditoprj%/entity/Synccontact_entity/entityfields/contact_id/linkedContextProcess.js</linkedContextProcess> + </entityField> + <entityField> + <name>SYNCCONTACTID</name> + </entityField> + <entityField> + <name>UPDATECONTACT</name> + <title>Will be updated</title> + <dropDownProcess>%aditoprj%/entity/Synccontact_entity/entityfields/updatecontact/dropDownProcess.js</dropDownProcess> + </entityField> + <entityField> + <name>DATE_DEL</name> + <title>Will be deleted</title> + <dropDownProcess>%aditoprj%/entity/Synccontact_entity/entityfields/date_del/dropDownProcess.js</dropDownProcess> + </entityField> + <entityField> + <name>EXCHANGEID</name> + <title>Synchronized with Outlook</title> + <dropDownProcess>%aditoprj%/entity/Synccontact_entity/entityfields/exchangeid/dropDownProcess.js</dropDownProcess> + </entityField> + <entityField> + <name>ORGANISATION_NAME</name> + <title>Organisation</title> + </entityField> + <entityField> + <name>FIRSTNAME</name> + <title>Firstname</title> + </entityField> + <entityField> + <name>LASTNAME</name> + <title>Lastname</title> + </entityField> + <entityField> + <name>STREET</name> + <title>Street</title> + </entityField> + <entityField> + <name>BUILDINGNO</name> + <title>Building no.</title> + </entityField> + <entityField> + <name>ZIP</name> + <title>Zip</title> + </entityField> + <entityField> + <name>CITY</name> + <title>City</title> + </entityField> + <entityField> + <name>COUNTRY</name> + <title>Country</title> + </entityField> + <entityField> + <name>PERSSALUTATION</name> + <title>Salutation</title> + </entityField> + <entityField> + <name>PICTURE</name> + <contentType>IMAGE</contentType> + </entityField> + <entityConsumer> + <name>AnyContacts</name> + <dependency> + <name>dependency</name> + <entityName>AnyContact_entity</entityName> + <fieldName>#PROVIDER</fieldName> + </dependency> + </entityConsumer> + <entityField> + <name>PERSON_ID</name> + </entityField> + <entityField> + <name>ORGANISATION_ID</name> + </entityField> + <entityField> + <name>TARGETCONTEXT</name> + </entityField> + <entityField> + <name>STREET_BUILDINGNO</name> + <title>Street</title> + </entityField> + <entityField> + <name>countDelete</name> + <title>Will be deleted</title> + <valueProcess>%aditoprj%/entity/Synccontact_entity/entityfields/countdelete/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>countInsert</name> + <title>Will be inserted</title> + <valueProcess>%aditoprj%/entity/Synccontact_entity/entityfields/countinsert/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>countUpdate</name> + <title>Will be updated</title> + <valueProcess>%aditoprj%/entity/Synccontact_entity/entityfields/countupdate/valueProcess.js</valueProcess> + </entityField> + <entityParameter> + <name>DataCondition_param</name> + <expose v="true" /> + </entityParameter> + <entityField> + <name>lastRunSynctable</name> + <title>Last process start: synchronize in ADITO</title> + <color>user-color-16</color> + <valueProcess>%aditoprj%/entity/Synccontact_entity/entityfields/lastrunsynctable/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>lastRunOutlook</name> + <title>Last process start: synchronize to Outlook</title> + <color>user-color-16</color> + <valueProcess>%aditoprj%/entity/Synccontact_entity/entityfields/lastrunoutlook/valueProcess.js</valueProcess> + </entityField> + <entityField> + <name>contactType</name> + <title>Contact type</title> + </entityField> + </entityFields> + <recordContainers> + <dbRecordContainer> + <name>db</name> + <fromClauseProcess>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/fromClauseProcess.js</fromClauseProcess> + <conditionProcess>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/conditionProcess.js</conditionProcess> + <alias>Data_alias</alias> + <recordFieldMappings> + <dbRecordFieldMapping> + <name>SYNCCONTACTID.value</name> + <recordfield>AB_SYNCCONTACT.SYNCCONTACTID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>DATE_DEL.value</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/date_del.value/expression.js</expression> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>UPDATECONTACT.value</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/updatecontact.value/expression.js</expression> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>USER_ID.value</name> + <recordfield>AB_SYNCCONTACT.USER_ID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>FIRSTNAME.value</name> + <recordfield>PERSON.FIRSTNAME</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>LASTNAME.value</name> + <recordfield>PERSON.LASTNAME</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>ORGANISATION_NAME.value</name> + <recordfield>ORGANISATION.NAME</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>CONTACT_ID.value</name> + <recordfield>AB_SYNCCONTACT.CONTACT_ID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>CITY.value</name> + <recordfield>ADDRESS.CITY</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>COUNTRY.value</name> + <recordfield>ADDRESS.COUNTRY</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>STREET.value</name> + <recordfield>ADDRESS.ADDRESS</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>ZIP.value</name> + <recordfield>ADDRESS.ZIP</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>BUILDINGNO.value</name> + <recordfield>ADDRESS.BUILDINGNO</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>PERSSALUTATION.value</name> + <recordfield>PERSON.SALUTATION</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>EXCHANGEID.value</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/exchangeid.value/expression.js</expression> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>PICTURE.value</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/picture.value/expression.js</expression> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>ORGANISATION_ID.value</name> + <recordfield>CONTACT.ORGANISATION_ID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>PERSON_ID.value</name> + <recordfield>CONTACT.PERSON_ID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>CONTACT_ID.displayValue</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js</expression> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>TARGETCONTEXT.value</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/targetcontext.value/expression.js</expression> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>UPDATECONTACT.displayValue</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/updatecontact.displayvalue/expression.js</expression> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>EXCHANGEID.displayValue</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/exchangeid.displayvalue/expression.js</expression> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>DATE_DEL.displayValue</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/date_del.displayvalue/expression.js</expression> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>contactType.value</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/contacttype.value/expression.js</expression> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>STREET_BUILDINGNO.value</name> + <expression>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/street_buildingno.value/expression.js</expression> + </dbRecordFieldMapping> + </recordFieldMappings> + <linkInformation> + <linkInformation> + <name>a662f8d1-5385-42da-ac98-d451ec052844</name> + <tableName>AB_SYNCCONTACT</tableName> + <primaryKey>SYNCCONTACTID</primaryKey> + <isUIDTable v="true" /> + <readonly v="false" /> + </linkInformation> + <linkInformation> + <name>bc5bc183-765b-4a43-b7c3-004478a2a128</name> + <tableName>PERSON</tableName> + <primaryKey>PERSONID</primaryKey> + <isUIDTable v="false" /> + <readonly v="true" /> + </linkInformation> + <linkInformation> + <name>7133d0fd-ae93-4b29-a15d-2b6d700cb348</name> + <tableName>CONTACT</tableName> + <primaryKey>CONTACTID</primaryKey> + <isUIDTable v="false" /> + <readonly v="true" /> + </linkInformation> + <linkInformation> + <name>6eec76b5-b6d6-4b23-8f3e-99ce42f65acb</name> + <tableName>ORGANISATION</tableName> + <primaryKey>ORGANISATIONID</primaryKey> + <isUIDTable v="false" /> + <readonly v="true" /> + </linkInformation> + <linkInformation> + <name>3308afe2-156e-4930-ab27-f7077014c41b</name> + <tableName>ADDRESS</tableName> + <primaryKey>ADDRESSID</primaryKey> + <isUIDTable v="false" /> + <readonly v="true" /> + </linkInformation> + </linkInformation> + <filterExtensions> + <filterExtension> + <name>UserId_filter</name> + <title>User</title> + <contentType>TEXT</contentType> + <filterConditionProcess>%aditoprj%/entity/Synccontact_entity/recordcontainers/db/filterextensions/userid_filter/filterConditionProcess.js</filterConditionProcess> + <filtertype>BASIC</filtertype> + </filterExtension> + </filterExtensions> + </dbRecordContainer> + </recordContainers> +</entity> diff --git a/entity/Synccontact_entity/entityfields/contact_id/linkedContextProcess.js b/entity/Synccontact_entity/entityfields/contact_id/linkedContextProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..aaeec99c3d3c9e6fb994a1d6abccd23c5d866d96 --- /dev/null +++ b/entity/Synccontact_entity/entityfields/contact_id/linkedContextProcess.js @@ -0,0 +1,5 @@ +import("system.vars"); +import("Contact_lib"); +import("system.result"); + +result.string(ContactUtils.getContextByPersOrg(vars.get("$field.PERSON_ID"), vars.get("$field.ORGANISATION_ID"))); \ No newline at end of file diff --git a/entity/Synccontact_entity/entityfields/countdelete/valueProcess.js b/entity/Synccontact_entity/entityfields/countdelete/valueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..1822fcfceb48db13df5759016bdd358f6ab6b468 --- /dev/null +++ b/entity/Synccontact_entity/entityfields/countdelete/valueProcess.js @@ -0,0 +1,5 @@ +import("Sql_lib"); +import("system.result"); +import("system.db"); + +result.string(newSelect("count(*)").from("AB_SYNCCONTACT").where("AB_SYNCCONTACT.DATE_DEL is not null").cell()); diff --git a/entity/Synccontact_entity/entityfields/countinsert/valueProcess.js b/entity/Synccontact_entity/entityfields/countinsert/valueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..44aa085d5dc0ed9f572c19710e691d715bf83103 --- /dev/null +++ b/entity/Synccontact_entity/entityfields/countinsert/valueProcess.js @@ -0,0 +1,5 @@ +import("Sql_lib"); +import("system.result"); +import("system.db"); + +result.string(newSelect("count(*)").from("AB_SYNCCONTACT").where("AB_SYNCCONTACT.EXCHANGEID is null").cell()); diff --git a/entity/Synccontact_entity/entityfields/countupdate/valueProcess.js b/entity/Synccontact_entity/entityfields/countupdate/valueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..df43173a07039a1256dd06f8ed891c634ebc5f32 --- /dev/null +++ b/entity/Synccontact_entity/entityfields/countupdate/valueProcess.js @@ -0,0 +1,5 @@ +import("Sql_lib"); +import("system.result"); +import("system.db"); + +result.string(newSelect("count(*)").from("AB_SYNCCONTACT").where("AB_SYNCCONTACT.UPDATECONTACT", 1).cell()); \ No newline at end of file diff --git a/entity/Synccontact_entity/entityfields/date_del/dropDownProcess.js b/entity/Synccontact_entity/entityfields/date_del/dropDownProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..1a6b597ac7fca1057f04d37b7f7e11ed61b7da63 --- /dev/null +++ b/entity/Synccontact_entity/entityfields/date_del/dropDownProcess.js @@ -0,0 +1,7 @@ +import("system.translate"); +import("system.result"); + +result.object([ + ["Yes", translate.text("Yes")] + ,["No", translate.text("No")] + ]); \ No newline at end of file diff --git a/entity/Synccontact_entity/entityfields/exchangeid/dropDownProcess.js b/entity/Synccontact_entity/entityfields/exchangeid/dropDownProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..1a6b597ac7fca1057f04d37b7f7e11ed61b7da63 --- /dev/null +++ b/entity/Synccontact_entity/entityfields/exchangeid/dropDownProcess.js @@ -0,0 +1,7 @@ +import("system.translate"); +import("system.result"); + +result.object([ + ["Yes", translate.text("Yes")] + ,["No", translate.text("No")] + ]); \ No newline at end of file diff --git a/entity/Synccontact_entity/entityfields/lastrunoutlook/valueProcess.js b/entity/Synccontact_entity/entityfields/lastrunoutlook/valueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..42d788931ecd91e59f5e0efef42bda7b0ed44f81 --- /dev/null +++ b/entity/Synccontact_entity/entityfields/lastrunoutlook/valueProcess.js @@ -0,0 +1,10 @@ +import("Sql_lib"); +import("system.translate"); +import("system.datetime"); +import("system.result"); +import("system.db"); + +var lastRun = newSelect("ASYS_TIMERS_SERVERRUNS.LASTRUN", SqlUtils.getSystemAlias()).from("ASYS_TIMERS_SERVERRUNS") +.where("ASYS_TIMERS_SERVERRUNS.TIMERID", "EwsSyncToExchange_serverProcess.process").cell(); + +result.string(datetime.toDate(lastRun, translate.text("dd/MM/yyyy HH:mm"), "UTC")); \ No newline at end of file diff --git a/entity/Synccontact_entity/entityfields/lastrunsynctable/valueProcess.js b/entity/Synccontact_entity/entityfields/lastrunsynctable/valueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..0400aa23d5bae78f8da36f724573cda6d865fa21 --- /dev/null +++ b/entity/Synccontact_entity/entityfields/lastrunsynctable/valueProcess.js @@ -0,0 +1,11 @@ +import("Sql_lib"); +import("system.translate"); +import("system.datetime"); +import("system.result"); +import("system.db"); + +var lastRun = newSelect("ASYS_TIMERS_SERVERRUNS.LASTRUN", SqlUtils.getSystemAlias()) +.from("ASYS_TIMERS_SERVERRUNS") +.where("ASYS_TIMERS_SERVERRUNS.TIMERID", "EwsSyncContact_serverProcess.process").cell(); + +result.string(datetime.toDate(lastRun, translate.text("dd/MM/yyyy HH:mm"), "UTC")); \ No newline at end of file diff --git a/entity/Synccontact_entity/entityfields/updatecontact/dropDownProcess.js b/entity/Synccontact_entity/entityfields/updatecontact/dropDownProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..1a6b597ac7fca1057f04d37b7f7e11ed61b7da63 --- /dev/null +++ b/entity/Synccontact_entity/entityfields/updatecontact/dropDownProcess.js @@ -0,0 +1,7 @@ +import("system.translate"); +import("system.result"); + +result.object([ + ["Yes", translate.text("Yes")] + ,["No", translate.text("No")] + ]); \ No newline at end of file diff --git a/entity/Synccontact_entity/recordcontainers/db/conditionProcess.js b/entity/Synccontact_entity/recordcontainers/db/conditionProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..9536d744d1f04662b84c5ec6b727d06aefccb799 --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/conditionProcess.js @@ -0,0 +1,19 @@ +import("Employee_lib"); +import("Sql_lib"); +import("system.result"); +import("system.vars"); + +var dataCond = vars.get("$param.DataCondition_param"); + +var condition = newWhere(); + +if(dataCond == "PersonalFilterView") +{ + condition.and("AB_SYNCCONTACT.USER_ID", EmployeeUtils.getCurrentUserId()); +} +else if(dataCond == "PendingUsersFilterView") +{ + condition.and("AB_SYNCCONTACT.EXCHANGEID is null"); +} + +result.string(condition.toString()); \ No newline at end of file diff --git a/entity/Synccontact_entity/recordcontainers/db/filterextensions/userid_filter/filterConditionProcess.js b/entity/Synccontact_entity/recordcontainers/db/filterextensions/userid_filter/filterConditionProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..d1cb89220f42f4a4dc945b98df674b9cbd942ebe --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/filterextensions/userid_filter/filterConditionProcess.js @@ -0,0 +1,55 @@ +import("system.db"); +import("system.vars"); +import("system.result"); +import("Sql_lib"); + +var rawvalue = (vars.get("$local.rawvalue") ? vars.get("$local.rawvalue") : ""); +var operator2 = vars.get("$local.operator2").trim(); +var comparison = vars.get("$local.comparison"); + +var userIdsCond = newSelect("ASYS_USERS.NAME", SqlUtils.getSystemAlias()) +.from("ASYS_USERS") +.where("ASYS_USERS.PROPKEY", 'title'); + +var operator; +var resultCond = newWhere(); + +switch (comparison) +{ + case "EQUAL": + operator = SqlBuilder.EQUAL(); + break; + case "NOT_EQUAL": + operator = SqlBuilder.NOT_EQUAL(); + break; + case "CONTAINS": + operator = SqlBuilder.LIKE(); + rawvalue = "%" + rawvalue + "%"; + break; + case "CONTAINSNOT": + operator = SqlBuilder.NOT_LIKE(); + rawvalue = "%" + rawvalue + "%"; + break; + case "STARTSWITH": + operator = SqlBuilder.LIKE(); + rawvalue = rawvalue + "%"; + break; + case "ENDSWITH": + operator = SqlBuilder.LIKE(); + rawvalue = "%" + rawvalue; + break; + case "ISNULL": + resultCond.and("AB_SYNCCONTACT.USER_ID is null"); + break; + case "ISNOTNULL": + resultCond.and("AB_SYNCCONTACT.USER_ID is not null"); + break; +} + +if(operator) +{ + userIdsCond.andIfSet("ASYS_USERS.PROPVAL", rawvalue, operator); + var userIds = userIdsCond.arrayColumn(); + resultCond.andIfSet("AB_SYNCCONTACT.USER_ID", userIds, SqlBuilder.IN()); +} +result.string(resultCond.toString()); \ No newline at end of file diff --git a/entity/Synccontact_entity/recordcontainers/db/fromClauseProcess.js b/entity/Synccontact_entity/recordcontainers/db/fromClauseProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..b89b4bb9d472fd1ddd7cabdf8bc86eefcfbb1132 --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/fromClauseProcess.js @@ -0,0 +1,10 @@ +import("Sql_lib"); +import("system.result"); + +var fromSql = new SqlBuilder().from("AB_SYNCCONTACT") +.join("CONTACT", "CONTACT.CONTACTID = AB_SYNCCONTACT.CONTACT_ID") +.leftJoin("PERSON", "PERSON.PERSONID = CONTACT.PERSON_ID") +.leftJoin("ORGANISATION", "ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID") +.leftJoin("ADDRESS", "ADDRESS.ADDRESSID = CONTACT.ADDRESS_ID") + +result.string(fromSql.toString()); \ No newline at end of file diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..c7d3535a56862c669ebdb3acc19da53a1868a91f --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/contact_id.displayvalue/expression.js @@ -0,0 +1,4 @@ +import("Contact_lib"); +import("system.result"); + +result.string(ContactUtils.getResolvingDisplaySubSql("AB_SYNCCONTACT.CONTACT_ID")); \ No newline at end of file diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/contacttype.value/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/contacttype.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..fb2ab84b028a23fc6bf10c65a1feda974d15a348 --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/contacttype.value/expression.js @@ -0,0 +1,8 @@ +import("Sql_lib"); +import("system.translate"); +import("system.result"); + +result.string(SqlBuilder.caseWhen("CONTACT.PERSON_ID is null") + .thenString(translate.text("Organisation")) + .elseString(translate.text("Contact")) + .toString()); diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/date_del.displayvalue/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/date_del.displayvalue/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..a5b91d55ad64c277df1b0666e76d1bf1a8b203a1 --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/date_del.displayvalue/expression.js @@ -0,0 +1,8 @@ +import("Sql_lib"); +import("system.result"); +import("system.translate"); + +result.string(SqlBuilder.caseWhen("AB_SYNCCONTACT.DATE_DEL is not null") + .thenString(translate.text("Yes")) + .elseString(translate.text("No")) + .toString()); diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/date_del.value/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/date_del.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..3ada13666620490d211fb27761a94cb36a6b5bdf --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/date_del.value/expression.js @@ -0,0 +1,8 @@ +import("Sql_lib"); +import("system.translate"); +import("system.result"); + +result.string(SqlBuilder.caseWhen("AB_SYNCCONTACT.DATE_DEL is not null") + .thenString("1") + .elseString("0") + .toString()); \ No newline at end of file diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/exchangeid.displayvalue/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/exchangeid.displayvalue/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..e4784d3be3020b365a107f2f9249c4c4016f6e30 --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/exchangeid.displayvalue/expression.js @@ -0,0 +1,8 @@ +import("Sql_lib"); +import("system.result"); +import("system.translate"); + +result.string(SqlBuilder.caseWhen("AB_SYNCCONTACT.EXCHANGEID is not null") + .thenString(translate.text("Yes")) + .elseString(translate.text("No")) + .toString()); diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/exchangeid.value/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/exchangeid.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..1caa628a958263c152c395f77041f06067fa7dc7 --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/exchangeid.value/expression.js @@ -0,0 +1,8 @@ +import("Sql_lib"); +import("system.translate"); +import("system.result"); + +result.string(SqlBuilder.caseWhen("AB_SYNCCONTACT.EXCHANGEID is not null") + .thenString("1") + .elseString("0") + .toString()); diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/picture.value/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/picture.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..808f2506f8777f445e7dcae99f1e7c4e1565a52e --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/picture.value/expression.js @@ -0,0 +1,10 @@ +import("Sql_lib"); +import("system.result"); + +var sqlMask = new SqlMaskingUtils(); + +var sql = SqlBuilder.caseWhen("PERSON.LASTNAME is not null") +.then(sqlMask.concatenate(["'Text:'", sqlMask.concatWithSeparator(["PERSON.FIRSTNAME", "PERSON.LASTNAME"])])) +.elseValue(sqlMask.concatenate(["'TEXT:'", "ORGANISATION.NAME"])); + +result.string(sql.toString()); diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/street_buildingno.value/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/street_buildingno.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..3ba99be53f900823e2e08d6b64170cdc5298ac69 --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/street_buildingno.value/expression.js @@ -0,0 +1,5 @@ +import("Sql_lib"); +import("system.result"); + +var sqlHelper = new SqlMaskingUtils(); +result.string(sqlHelper.concatWithSeparator(["ADDRESS.ADDRESS", "ADDRESS.BUILDINGNO"])); \ No newline at end of file diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/targetcontext.value/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/targetcontext.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..5c2b1dc8630ed5fb951747e001005c8803f131b2 --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/targetcontext.value/expression.js @@ -0,0 +1,10 @@ +import("Sql_lib"); +import("Context_lib"); +import("system.result"); + +result.string(SqlBuilder.caseWhen("CONTACT.PERSON_ID is null") + .thenString(ContextUtils.getContextName("Organisation")) + .elseValue( + SqlBuilder.caseWhen("CONTACT.ORGANISATION_ID is not null and CONTACT.PERSON_ID is not null") + .thenString(ContextUtils.getContextName("Person")) + ).toString()); \ No newline at end of file diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/updatecontact.displayvalue/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/updatecontact.displayvalue/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..3eee58f108b07f709e0d424dc0f69418e69a8470 --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/updatecontact.displayvalue/expression.js @@ -0,0 +1,8 @@ +import("Sql_lib"); +import("system.result"); +import("system.translate"); + +result.string(SqlBuilder.caseWhen("AB_SYNCCONTACT.UPDATECONTACT", 1) + .thenString(translate.text("Yes")) + .elseString(translate.text("No")) + .toString()); \ No newline at end of file diff --git a/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/updatecontact.value/expression.js b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/updatecontact.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..18da00e958046ae4dc2027540cc6927642a21637 --- /dev/null +++ b/entity/Synccontact_entity/recordcontainers/db/recordfieldmappings/updatecontact.value/expression.js @@ -0,0 +1,9 @@ +import("Sql_lib"); +import("system.result"); +import("system.translate"); + +//this case statement is needed because the UPDATECONTACT column can also contain a null value +result.string(SqlBuilder.caseWhen("AB_SYNCCONTACT.UPDATECONTACT", 1) + .thenString("1") + .elseString("0") + .toString()); \ No newline at end of file diff --git a/entity/SyncedSearches_entity/SyncedSearches_entity.aod b/entity/SyncedSearches_entity/SyncedSearches_entity.aod new file mode 100644 index 0000000000000000000000000000000000000000..f0b33a8b3b6d36278be2b2077ae1f28e57199d4e --- /dev/null +++ b/entity/SyncedSearches_entity/SyncedSearches_entity.aod @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="UTF-8"?> +<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.3.22" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.3.22"> + <name>SyncedSearches_entity</name> + <title>Synced searches</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <titlePlural>Synced searches</titlePlural> + <recordContainer>db</recordContainer> + <entityFields> + <entityProvider> + <name>#PROVIDER</name> + </entityProvider> + <entityProvider> + <name>#PROVIDER_AGGREGATES</name> + <useAggregates v="true" /> + </entityProvider> + <entityField> + <name>ID</name> + </entityField> + <entityField> + <name>PROPKEY</name> + </entityField> + <entityField> + <name>PROPVAL</name> + </entityField> + <entityField> + <name>USER_ID</name> + <title>User</title> + </entityField> + <entityField> + <name>PROPVAL_CLOB</name> + <title>Information</title> + <displayValueProcess>%aditoprj%/entity/SyncedSearches_entity/entityfields/propval_clob/displayValueProcess.js</displayValueProcess> + </entityField> + <entityField> + <name>DATE_NEW</name> + <title>Creation date</title> + <contentType>DATE</contentType> + <resolution>MINUTE</resolution> + </entityField> + <entityField> + <name>GROUPID</name> + </entityField> + <entityActionGroup> + <name>ExportFilter</name> + <children> + <entityActionField> + <name>ExportFilterToContacts</name> + <title>Show filter result</title> + <onActionProcess>%aditoprj%/entity/SyncedSearches_entity/entityfields/exportfilter/children/exportfiltertocontacts/onActionProcess.js</onActionProcess> + <selectionType>MULTI</selectionType> + <iconId>NEON:EXPORT</iconId> + <tooltip>Show filter result</tooltip> + </entityActionField> + <entityActionField> + <name>ManualResynchronization</name> + <title>Manual resynchronization of user</title> + <onActionProcess>%aditoprj%/entity/SyncedSearches_entity/entityfields/exportfilter/children/manualresynchronization/onActionProcess.js</onActionProcess> + <selectionType>MULTI</selectionType> + <iconId>VAADIN:REFRESH</iconId> + <tooltip>Manual resynchronization of user</tooltip> + </entityActionField> + </children> + </entityActionGroup> + <entityField> + <name>filter</name> + <title>Filter</title> + </entityField> + </entityFields> + <recordContainers> + <dbRecordContainer> + <name>db</name> + <fromClauseProcess>%aditoprj%/entity/SyncedSearches_entity/recordcontainers/db/fromClauseProcess.js</fromClauseProcess> + <conditionProcess>%aditoprj%/entity/SyncedSearches_entity/recordcontainers/db/conditionProcess.js</conditionProcess> + <orderClauseProcess>%aditoprj%/entity/SyncedSearches_entity/recordcontainers/db/orderClauseProcess.js</orderClauseProcess> + <alias>_____SYSTEMALIAS</alias> + <recordFieldMappings> + <dbRecordFieldMapping> + <name>ID.value</name> + <recordfield>ASYS_USERS.ID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>PROPKEY.value</name> + <recordfield>ASYS_USERS.PROPKEY</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>PROPVAL.value</name> + <recordfield>ASYS_USERS.PROPVAL</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>PROPVAL_CLOB.value</name> + <recordfield>ASYS_USERS.PROPVAL_CLOB</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>USER_ID.value</name> + <expression>%aditoprj%/entity/SyncedSearches_entity/recordcontainers/db/recordfieldmappings/user_id.value/expression.js</expression> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>DATE_NEW.value</name> + <recordfield>ASYS_USERS.DATE_NEW</recordfield> + <isFilterable v="true" /> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>GROUPID.value</name> + <recordfield>ASYS_USERS.GROUPID</recordfield> + </dbRecordFieldMapping> + <dbRecordFieldMapping> + <name>filter.value</name> + <expression>%aditoprj%/entity/SyncedSearches_entity/recordcontainers/db/recordfieldmappings/filter.value/expression.js</expression> + </dbRecordFieldMapping> + </recordFieldMappings> + <linkInformation> + <linkInformation> + <name>90aebc95-1cc7-4c1b-af29-a2d048c57778</name> + <tableName>ASYS_USERS</tableName> + <primaryKey>ID</primaryKey> + <isUIDTable v="true" /> + <readonly v="false" /> + </linkInformation> + </linkInformation> + </dbRecordContainer> + </recordContainers> +</entity> diff --git a/entity/SyncedSearches_entity/entityfields/exportfilter/children/exportfiltertocontacts/onActionProcess.js b/entity/SyncedSearches_entity/entityfields/exportfilter/children/exportfiltertocontacts/onActionProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..c88781d813cc5f841e7b46f72c5282fb86772b40 --- /dev/null +++ b/entity/SyncedSearches_entity/entityfields/exportfilter/children/exportfiltertocontacts/onActionProcess.js @@ -0,0 +1,24 @@ +import("system.neon"); +import("system.db"); +import("system.vars"); + +var groupId = vars.get("$field.GROUPID"); +//the groupId field contains the name of the group of a filter e.g "FILTER:Organisation_entity.SAVED" in order to get the entity name where the filter is used +//it gets substringed by the part which is always the same -> so "Organisation_entity" would be returned with the example above +groupId = groupId.substring(7, groupId.length - 6); + +var search = JSON.parse(vars.get("$field.filter"))["search"]; //searchpart of the JSON + +var params = +{ + "SearchSyncCondition_param" : JSON.stringify(search) +}; + +if(groupId == "Organisation_entity") +{ + neon.openContext("Organisation", "OrganisationFilter_view", null, neon.OPERATINGSTATE_SEARCH, params); +} +else +{ + neon.openContext("Person", "PersonFilter_view", null, neon.OPERATINGSTATE_SEARCH, params); +} \ No newline at end of file diff --git a/entity/SyncedSearches_entity/entityfields/exportfilter/children/manualresynchronization/onActionProcess.js b/entity/SyncedSearches_entity/entityfields/exportfilter/children/manualresynchronization/onActionProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..9be8ee72a4e6aa22899dc7e70d52a23464b0189f --- /dev/null +++ b/entity/SyncedSearches_entity/entityfields/exportfilter/children/manualresynchronization/onActionProcess.js @@ -0,0 +1,25 @@ +import("system.neon"); +import("Sql_lib"); +import("system.tools"); +import("system.vars"); +import("system.translate"); +import("system.question"); +import("system.db"); + +var deleteYesNo = question.askYesNo(translate.text("Manual resynchronization"), +translate.text("Do you really want to resynchronize the user completely?\nThe synchronisation in ADITO will be deleted.\nThe outlook contacts must be cleared manually."), true); + +if(deleteYesNo) +{ + var userTitle = vars.get("$field.USER_ID"); + var user = tools.getUser(userTitle, tools.PROFILE_FULL); + if(user) + { + var userParam = user[tools.NAME]; + + db.deleteData("ASYS_USERS", "NAME = '" + userParam + "' and PROPKEY = 'SearchSync'", SqlUtils.getSystemAlias()); + db.deleteData("AB_SYNCCONTACT", "USER_ID = '" + userParam + "'", "Data_alias"); + } + + neon.refresh(); +} \ No newline at end of file diff --git a/entity/SyncedSearches_entity/entityfields/propval_clob/displayValueProcess.js b/entity/SyncedSearches_entity/entityfields/propval_clob/displayValueProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..d426b8638e563a3484552d2f10e5617b81f3f518 --- /dev/null +++ b/entity/SyncedSearches_entity/entityfields/propval_clob/displayValueProcess.js @@ -0,0 +1,9 @@ +import("EwsSyncContact_lib"); +import("system.project"); +import("system.translate"); +import("system.result"); +import("system.vars"); + +var res = vars.get("$field.PROPVAL_CLOB"); + +result.string(translate.withArguments(res, [project.getPreferenceValue("custom.ews.syncsize", EwsClientSyncUtils.getMaxSyncSize() )])); \ No newline at end of file diff --git a/entity/SyncedSearches_entity/recordcontainers/db/conditionProcess.js b/entity/SyncedSearches_entity/recordcontainers/db/conditionProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..e1bebb6cfe7f269d43ccb026a02446a67cf8c1be --- /dev/null +++ b/entity/SyncedSearches_entity/recordcontainers/db/conditionProcess.js @@ -0,0 +1,6 @@ +import("system.result"); +import("Sql_lib"); + +var condition = newWhere().and("ASYS_USERS.PROPKEY", 'SearchSync'); + +result.string(condition.toString()); diff --git a/entity/SyncedSearches_entity/recordcontainers/db/fromClauseProcess.js b/entity/SyncedSearches_entity/recordcontainers/db/fromClauseProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..30376e8653469cc5002ab17d65dba0b1bba822a9 --- /dev/null +++ b/entity/SyncedSearches_entity/recordcontainers/db/fromClauseProcess.js @@ -0,0 +1,3 @@ +import("system.result"); + +result.string("ASYS_USERS join ASYS_USERS titleInfo on ASYS_USERS.NAME = titleInfo.NAME and titleInfo.PROPKEY = 'title'"); \ No newline at end of file diff --git a/entity/SyncedSearches_entity/recordcontainers/db/orderClauseProcess.js b/entity/SyncedSearches_entity/recordcontainers/db/orderClauseProcess.js new file mode 100644 index 0000000000000000000000000000000000000000..120439d0d3a56f2e26e0bdf5fc1153345716cf13 --- /dev/null +++ b/entity/SyncedSearches_entity/recordcontainers/db/orderClauseProcess.js @@ -0,0 +1,4 @@ +import("system.result"); +import("system.db"); + +result.object({"titleInfo.PROPVAL": db.ASCENDING}); \ No newline at end of file diff --git a/entity/SyncedSearches_entity/recordcontainers/db/recordfieldmappings/filter.value/expression.js b/entity/SyncedSearches_entity/recordcontainers/db/recordfieldmappings/filter.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..ac15dc55fa01b24822f50717ee7eeae6e990d917 --- /dev/null +++ b/entity/SyncedSearches_entity/recordcontainers/db/recordfieldmappings/filter.value/expression.js @@ -0,0 +1,7 @@ +import("Sql_lib"); +import("system.result"); + +result.string(newSelect("innerAsysUsers.PROPVAL_CLOB") + .from("ASYS_USERS", "innerAsysUsers") + .where("innerAsysUsers.ID = ASYS_USERS.PROPVAL") + .toString()); \ No newline at end of file diff --git a/entity/SyncedSearches_entity/recordcontainers/db/recordfieldmappings/user_id.value/expression.js b/entity/SyncedSearches_entity/recordcontainers/db/recordfieldmappings/user_id.value/expression.js new file mode 100644 index 0000000000000000000000000000000000000000..de8dbe4dcd681523a4b65462623ad33044c91bb3 --- /dev/null +++ b/entity/SyncedSearches_entity/recordcontainers/db/recordfieldmappings/user_id.value/expression.js @@ -0,0 +1,3 @@ +import("system.result"); + +result.string("titleInfo.PROPVAL"); \ No newline at end of file diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod index 09e836d4a1c3f4ad82ee7a787fbf977673b70e01..eb553a93aaba74c7610d535e8b4e62c6987f727b 100644 --- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod +++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod @@ -10784,6 +10784,102 @@ <entry> <key>Answer Address</key> </entry> + <entry> + <key>Synchronized with Outlook</key> + </entry> + <entry> + <key>Will be inserted</key> + </entry> + <entry> + <key>Last process start: synchronize in ADITO</key> + </entry> + <entry> + <key>Shows all users which still have a pending synchronization to Outlook</key> + </entry> + <entry> + <key>Search synchronisations</key> + </entry> + <entry> + <key>Calling the abbyy webservice failed</key> + </entry> + <entry> + <key>Remove synchronization</key> + </entry> + <entry> + <key>Will be updated</key> + </entry> + <entry> + <key>EWS-Sync dashboard</key> + </entry> + <entry> + <key>Pending contacts</key> + </entry> + <entry> + <key>Search greater %0, sync. not possible</key> + </entry> + <entry> + <key>Synchronize</key> + </entry> + <entry> + <key>Will be deleted</key> + </entry> + <entry> + <key>Shows all synchronized contacts</key> + </entry> + <entry> + <key>within one Month</key> + </entry> + <entry> + <key>Last process start: synchronize to Outlook</key> + </entry> + <entry> + <key>Show filter in contacts</key> + </entry> + <entry> + <key>Valuation</key> + </entry> + <entry> + <key>Search synchronisation</key> + </entry> + <entry> + <key>My synchronized contacts</key> + </entry> + <entry> + <key>Synchronization status</key> + </entry> + <entry> + <key>All synchronized contacts</key> + </entry> + <entry> + <key>Contacts in Outlook</key> + </entry> + <entry> + <key>Shows all synchronized searches of the users</key> + </entry> + <entry> + <key>Shows the number of contacts still to be synchronized</key> + </entry> + <entry> + <key>Manual resynchronization of user</key> + </entry> + <entry> + <key>Pending synchronizations to Outlook</key> + </entry> + <entry> + <key>Shows my synchronized contacts</key> + </entry> + <entry> + <key>Synchronisation status</key> + </entry> + <entry> + <key>Synchronized searches</key> + </entry> + <entry> + <key>Do you really want to resynchronize the user completely?\nThe data in ADITO will be deleted.\nThe outlook contacts must be cleared manually.</key> + </entry> + <entry> + <key>Synced searches</key> + </entry> <entry> <key>Open new mosaico template</key> </entry> diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod index 2751e87f9046b70486aee5c950f9dcfd533f40f4..0fc5db493b31db1137932d4e1b3cb361e3c9a379 100644 --- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod +++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod @@ -241,14 +241,26 @@ <key>Not subscribed</key> <value>Nicht abonniert</value> </entry> + <entry> + <key>EWS-Sync dashboard</key> + <value>EWS-Sync-Dashboard</value> + </entry> <entry> <key>Set Test Recipient</key> <value>Testempfänger setzen</value> </entry> + <entry> + <key>Last process start: synchronize to Outlook</key> + <value>Letzter Prozessstart: Synchronisation nach Outlook</value> + </entry> <entry> <key>URL must be unique</key> <value>Die URL muss eindeutig sein!</value> </entry> + <entry> + <key>Will be inserted</key> + <value>Wird eingefügt</value> + </entry> <entry> <key>Opening Date</key> <value>Öffnungsdatum</value> @@ -261,6 +273,14 @@ <key>%0 out of %1 records were changed to \"%2\".\n %3 record/s could not be updated.</key> <value>%0 von %1 Datensätze wurden auf \"%2\" geändert.\n%3 Datensätze konnten nicht akutualisiert werden.</value> </entry> + <entry> + <key>Shows all synchronized datasets</key> + <value>Zeigt alle Synchronisierte Datensätze</value> + </entry> + <entry> + <key>Manual resynchronization of user</key> + <value>Manuelle Neusynchronisation des Benutzers</value> + </entry> <entry> <key>This setting is overridden by the setting '%0'</key> <value>Diese Einstellung wird durch die Einstellung '%0' überschrieben</value> @@ -317,6 +337,10 @@ <key>Interest (subscribed)</key> <value>Interesse (abonniert)</value> </entry> + <entry> + <key>Search synchronisation</key> + <value>Synchronisierte Suchen</value> + </entry> <entry> <key>Value is too small, the minimum is %0</key> <value>Wert ist zu klein, das Minimum ist %0</value> @@ -365,6 +389,10 @@ <key>change valid to</key> <value>Gültig bis ändern</value> </entry> + <entry> + <key>Synchronize</key> + <value>Synchronisieren</value> + </entry> <entry> <key>Channel type</key> <value>Kanalart</value> @@ -676,6 +704,10 @@ <key>Radius Search</key> <value>Umkreissuche</value> </entry> + <entry> + <key>Search greater %0, sync. not possible</key> + <value>Suche größer als %0, Synchronisierung nicht möglich</value> + </entry> <entry> <key>No file selected.</key> <value>Keine Datei ausgewählt.</value> @@ -1196,6 +1228,10 @@ <key>Number of activities</key> <value>Anzahl Aktivitäten</value> </entry> + <entry> + <key>Contact synchronisations</key> + <value>Kontaktsynchronisationen</value> + </entry> <entry> <key>${ATTRIBUTE_VOID}</key> <value>Tag</value> @@ -1487,6 +1523,10 @@ <key>None</key> <value>Keine</value> </entry> + <entry> + <key>Do you really want to resynchronize the user completely?\nThe synchronisation in ADITO will be deleted.\nThe outlook contacts must be cleared manually.</key> + <value>Wollen Sie den Benutzer wirklich komplett neu synchronisieren?\nDie Synchronisation wird aus ADITO gelöscht.\nDie Outlook-Kontakte müssen manuell gelöscht werden.</value> + </entry> <entry> <key>Edit workflow</key> <value>Workflow editieren</value> @@ -3015,6 +3055,10 @@ <key>November</key> <value>November</value> </entry> + <entry> + <key>Synced searches</key> + <value>Synchronisierte Suchen</value> + </entry> <entry> <key>Please update the ${FORECAST_ENGLISH}.</key> <value>Bitte den Forecast überprüfen.</value> @@ -3099,6 +3143,10 @@ <key>title</key> <value>Titel</value> </entry> + <entry> + <key>Dataset in Outlook</key> + <value>Datensatz in Outlook</value> + </entry> <entry> <key>{$TASK_PRIORITY_LOW}</key> <value>niedrig</value> @@ -3131,6 +3179,10 @@ <key>Salesdashboard</key> <value>Vertriebsdashboard</value> </entry> + <entry> + <key>Contact synchronisation dashboard</key> + <value>Kontaktsynchronisationsdashboard</value> + </entry> <entry> <key>Key Figures</key> <value>Kennzahlen</value> @@ -3146,6 +3198,10 @@ <key>Person</key> <value>Person</value> </entry> + <entry> + <key>Show filter result</key> + <value>Filterergebnis anzeigen</value> + </entry> <entry> <key>Detail</key> <value>Detail</value> @@ -4017,6 +4073,10 @@ <key>Malawi</key> <value>Malawi</value> </entry> + <entry> + <key>Synchronized with Outlook</key> + <value>Synchronisiert mit Outlook</value> + </entry> <entry> <key>Andorra</key> <value>Andorra</value> @@ -6033,6 +6093,10 @@ <key>OnPremise</key> <value>OnPremise</value> </entry> + <entry> + <key>All synchronized datasets</key> + <value>Alle synchronisierten Datensätze</value> + </entry> <entry> <key>Head of IT</key> <value>Leiter IT</value> @@ -8148,6 +8212,10 @@ <key>From buildingnumber</key> <value>ab Hausnummer</value> </entry> + <entry> + <key>Pending datasets</key> + <value>Ausstehende Datensätze</value> + </entry> <entry> <key>Resource</key> <value>Resource</value> @@ -8187,6 +8255,10 @@ <entry> <key>My Forecast and Turnover </key> </entry> + <entry> + <key>Will be deleted</key> + <value>Wird gelöscht</value> + </entry> <entry> <key>Shows my Forecast and Turnover for the actual year</key> <value>Zeigt meinen Forecast und meinen Umsatz für das aktuelle Jahr</value> @@ -9196,6 +9268,10 @@ Bitte Datumseingabe prüfen</value> <key>Export Template PlaceOfUse</key> <value>Exportvorlagenverwendungsort</value> </entry> + <entry> + <key>Search synchronisations</key> + <value>Synchronisierte Suchen</value> + </entry> <entry> <key>Exportfile \"%0\" can now be downloaded</key> <value>Exportdatei \"%0\" kann heruntergeladen werden</value> @@ -9671,10 +9747,18 @@ Bitte Datumseingabe prüfen</value> <key>End event</key> <value>End-Ereignis</value> </entry> + <entry> + <key>Synchronized searches</key> + <value>Synchronisierte Suchen</value> + </entry> <entry> <key>Receive task</key> <value>Empfangende Aufgabe</value> </entry> + <entry> + <key>Synchronisation status</key> + <value>Synchronisationsstatus</value> + </entry> <entry> <key>{$QUICK_ENTRY_LEAD_QUICK_ACQUISITION}</key> <value>Leadschnellerfassung</value> @@ -9810,6 +9894,10 @@ Bitte Datumseingabe prüfen</value> <key>The end date has to be after the start.</key> <value>Das Enddatum muss nach dem Startdatum kommen.</value> </entry> + <entry> + <key>Add to synchronisation</key> + <value>Zur Synchronisation hinzufügen</value> + </entry> <entry> <key>me</key> <value>ich</value> @@ -9981,6 +10069,10 @@ Bitte Datumseingabe prüfen</value> <entry> <key> number of connections</key> </entry> + <entry> + <key>Show filter in contacts</key> + <value>Filter in Kontakten anzeigen</value> + </entry> <entry> <key>Create salesproject touchpoint</key> <value>Vertriebsprojektberührungspunkt erstellen</value> @@ -10025,6 +10117,10 @@ Bitte Datumseingabe prüfen</value> <key>Limited Read Permission</key> <value>Eingeschränkte Leseberechtigung</value> </entry> + <entry> + <key>Datasets in Outlook</key> + <value>Datensätze in Outlook</value> + </entry> <entry> <key>Full details</key> <value>Alle Details</value> @@ -10089,6 +10185,10 @@ Bitte Datumseingabe prüfen</value> <key>Number of employees</key> <value>Anzahl Mitarbeiter</value> </entry> + <entry> + <key>Shows all synchronized searches of the users</key> + <value>Zeigt alle synchronisierten Suchen der Benutzer an</value> + </entry> <entry> <key>2. Customer value</key> <value>2. Kundenwert</value> @@ -10109,10 +10209,18 @@ Bitte Datumseingabe prüfen</value> <key>Headquarters</key> <value>Hauptsitz</value> </entry> + <entry> + <key>My synchronized datasets</key> + <value>Meine synchronisierten Datensätze</value> + </entry> <entry> <key>Current supply share</key> <value>Aktueller Lieferanteil</value> </entry> + <entry> + <key>Shows my synchronized datasets</key> + <value>Zeigt meine synchronisierten Datensätze an</value> + </entry> <entry> <key>Purchasing potential p. a.</key> <value>Einkaufspotential p. a.</value> @@ -10149,6 +10257,10 @@ Bitte Datumseingabe prüfen</value> <key>Full Permissions</key> <value>Komplette Berechtigungen</value> </entry> + <entry> + <key>Shows the number of datasets still to be synchronized</key> + <value>Zeigt die Anzahl der noch zu synchronisierenden Datensätze an</value> + </entry> <entry> <key>200-349 D€</key> <value>200-349 D€</value> @@ -10192,6 +10304,10 @@ Bitte Datumseingabe prüfen</value> <entry> <key>Valid from (as </key> </entry> + <entry> + <key>Shows all users which still have a pending synchronization to Outlook</key> + <value>Zeigt alle Benutzer an, die noch eine ausstehende Synchronisation mit Outlook haben</value> + </entry> <entry> <key>Sunday</key> <value>Sonntag</value> @@ -10805,6 +10921,10 @@ Bitte Datumseingabe prüfen</value> <key>Linked in (Person)</key> <value>Linked In (Person)</value> </entry> + <entry> + <key>Contact synchronisation</key> + <value>Kontaktsynchronisation</value> + </entry> <entry> <key>Mobile number (Organisation)</key> <value>Handynummer (Organisation)</value> @@ -10829,10 +10949,18 @@ Bitte Datumseingabe prüfen</value> <key>Blog (Organisation)</key> <value>Blog (Firma)</value> </entry> + <entry> + <key>Remove from synchronization</key> + <value>Aus Synchronisation entfernen</value> + </entry> <entry> <key>Internet (Person)</key> <value>Internet (Person)</value> </entry> + <entry> + <key>Pending synchronizations to Outlook</key> + <value>Ausstehende Synchronisationen nach Outlook</value> + </entry> <entry> <key>Mobile number (Person)</key> <value>Handynummer (Person)</value> @@ -12075,6 +12203,10 @@ Bitte Datumseingabe prüfen</value> <key>Done on</key> <value>Erledigt am</value> </entry> + <entry> + <key>Last process start: synchronize in ADITO</key> + <value>Letzter Prozessstart: Synchronisation in ADITO</value> + </entry> <entry> <key>Source / origin of the generation of contacts</key> <value>Quelle / Herkunft der Kontaktgenerierung</value> @@ -12095,6 +12227,10 @@ Bitte Datumseingabe prüfen</value> <key>Further customer meetings</key> <value>Weitere Kundengespräche</value> </entry> + <entry> + <key>Will be updated</key> + <value>Wird aktualisiert</value> + </entry> <entry> <key>Code</key> </entry> @@ -12266,6 +12402,9 @@ Bitte Datumseingabe prüfen</value> <key>Exclude existing workflows</key> <value>Nur nicht vorhandene Workflows</value> </entry> + <entry> + <key>Synchronization status</key> + </entry> <entry> <key>Open Mosaico</key> <value>Mosaico öffnen</value> @@ -14139,6 +14278,30 @@ Bitte Datumseingabe prüfen</value> <entry> <key>We save your data until</key> </entry> + <entry> + <key>Remove synchronization</key> + </entry> + <entry> + <key>Pending contacts</key> + </entry> + <entry> + <key>Shows all synchronized contacts</key> + </entry> + <entry> + <key>My synchronized contacts</key> + </entry> + <entry> + <key>All synchronized contacts</key> + </entry> + <entry> + <key>Contacts in Outlook</key> + </entry> + <entry> + <key>Shows the number of contacts still to be synchronized</key> + </entry> + <entry> + <key>Shows my synchronized contacts</key> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> </language> diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod index b9beadd214116a423d107856866cce8140fd63ba..eca5bdb37e9661df1c735f26e9258ceb2e9baaff 100644 --- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod +++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod @@ -10901,6 +10901,96 @@ <entry> <key>Contigent exhausted, please buy some new one to continue.</key> </entry> + <entry> + <key>Synchronized with Outlook</key> + </entry> + <entry> + <key>Will be inserted</key> + </entry> + <entry> + <key>Last process start: synchronize in ADITO</key> + </entry> + <entry> + <key>Shows all users which still have a pending synchronization to Outlook</key> + </entry> + <entry> + <key>Search synchronisations</key> + </entry> + <entry> + <key>Calling the abbyy webservice failed</key> + </entry> + <entry> + <key>Remove synchronization</key> + </entry> + <entry> + <key>Will be updated</key> + </entry> + <entry> + <key>EWS-Sync dashboard</key> + </entry> + <entry> + <key>Pending contacts</key> + </entry> + <entry> + <key>Search greater %0, sync. not possible</key> + </entry> + <entry> + <key>Synchronize</key> + </entry> + <entry> + <key>Will be deleted</key> + </entry> + <entry> + <key>Shows all synchronized contacts</key> + </entry> + <entry> + <key>Last process start: synchronize to Outlook</key> + </entry> + <entry> + <key>Show filter in contacts</key> + </entry> + <entry> + <key>Search synchronisation</key> + </entry> + <entry> + <key>My synchronized contacts</key> + </entry> + <entry> + <key>Synchronization status</key> + </entry> + <entry> + <key>All synchronized contacts</key> + </entry> + <entry> + <key>Contacts in Outlook</key> + </entry> + <entry> + <key>Shows all synchronized searches of the users</key> + </entry> + <entry> + <key>Shows the number of contacts still to be synchronized</key> + </entry> + <entry> + <key>Manual resynchronization of user</key> + </entry> + <entry> + <key>Pending synchronizations to Outlook</key> + </entry> + <entry> + <key>Shows my synchronized contacts</key> + </entry> + <entry> + <key>Synchronisation status</key> + </entry> + <entry> + <key>Synchronized searches</key> + </entry> + <entry> + <key>Do you really want to resynchronize the user completely?\nThe data in ADITO will be deleted.\nThe outlook contacts must be cleared manually.</key> + </entry> + <entry> + <key>Synced searches</key> + </entry> </keyValueMap> <font name="Dialog" style="0" size="11" /> </language> diff --git a/neonContext/SearchSync/SearchSync.aod b/neonContext/SearchSync/SearchSync.aod new file mode 100644 index 0000000000000000000000000000000000000000..bcac83ae7a84aadb36dad524d6e20dd066ae858d --- /dev/null +++ b/neonContext/SearchSync/SearchSync.aod @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.1.1"> + <name>SearchSync</name> + <title>Search Synchronisation</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <icon>VAADIN:SEARCH</icon> + <filterView>SearchSyncFilter_view</filterView> + <entity>SearchSync_entity</entity> + <references> + <neonViewReference> + <name>20ccae52-29e6-4f4d-bf75-bfd738fdb8f6</name> + <view>SearchSyncFilter_view</view> + </neonViewReference> + </references> +</neonContext> diff --git a/neonContext/Synccontact/Synccontact.aod b/neonContext/Synccontact/Synccontact.aod new file mode 100644 index 0000000000000000000000000000000000000000..9d21237d637698c2f4b70943615793fc9bad92f7 --- /dev/null +++ b/neonContext/Synccontact/Synccontact.aod @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.1.1"> + <name>Synccontact</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <icon>VAADIN:FILE_REFRESH</icon> + <filterView>SynccontactFilter_view</filterView> + <entity>Synccontact_entity</entity> + <references> + <neonViewReference> + <name>4170d8c1-072a-4f0c-b1d9-ae5f7c5e9f7e</name> + <view>SynccontactFilter_view</view> + </neonViewReference> + <neonViewReference> + <name>a2f2b551-da7d-4996-9723-b0212654e008</name> + <view>SynccontactCount_view</view> + </neonViewReference> + <neonViewReference> + <name>ff4bddc9-b551-4275-a4ce-3146e3b4d43e</name> + </neonViewReference> + </references> +</neonContext> diff --git a/neonContext/SyncedSearches/SyncedSearches.aod b/neonContext/SyncedSearches/SyncedSearches.aod new file mode 100644 index 0000000000000000000000000000000000000000..0d98a903a74984a07798c2000867a65342ddda86 --- /dev/null +++ b/neonContext/SyncedSearches/SyncedSearches.aod @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.1.1"> + <name>SyncedSearches</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <filterView>SyncedSearchesFilter_view</filterView> + <entity>SyncedSearches_entity</entity> + <references> + <neonViewReference> + <name>888f0183-1b4f-4538-8852-d67521058869</name> + <view>SyncedSearchesFilter_view</view> + </neonViewReference> + </references> +</neonContext> diff --git a/neonDashboard/EWSSyncDashboard/EWSSyncDashboard.aod b/neonDashboard/EWSSyncDashboard/EWSSyncDashboard.aod new file mode 100644 index 0000000000000000000000000000000000000000..24436d1d18133685ee60de05f13d297569295b72 --- /dev/null +++ b/neonDashboard/EWSSyncDashboard/EWSSyncDashboard.aod @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonDashboard 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/neonDashboard/1.1.0"> + <name>EWSSyncDashboard</name> + <title>Contact synchronisation dashboard</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <icon>VAADIN:FILE_REFRESH</icon> + <dashboardType>PRIVATE</dashboardType> + <editRoles> + <element>INTERNAL_ADMINISTRATOR</element> + </editRoles> + <defaultDashlets> + <neonDashlet> + <name>AllSyncedContactsDashlet</name> + <viewName>SynccontactFilter_view</viewName> + <configName>SynccontactAllFilterViewDashlet</configName> + <uiConfiguration> + <name>uiConfiguration</name> + <xPos v="0" /> + <yPos v="8" /> + <colspan v="3" /> + <rowspan v="4" /> + </uiConfiguration> + </neonDashlet> + <neonDashlet> + <name>SynchronizedSearchesDashlet</name> + <viewName>SyncedSearchesFilter_view</viewName> + <configName>SyncedSearchesTableFilterDashlet</configName> + <uiConfiguration> + <name>uiConfiguration</name> + <xPos v="0" /> + <yPos v="4" /> + <colspan v="2" /> + <rowspan v="4" /> + </uiConfiguration> + </neonDashlet> + <neonDashlet> + <name>CountSyncedContactsDashlet</name> + <viewName>SynccontactCount_view</viewName> + <configName>SynccontactScoreCardDashlet</configName> + <uiConfiguration> + <name>uiConfiguration</name> + <xPos v="2" /> + <yPos v="0" /> + <colspan v="1" /> + <rowspan v="8" /> + </uiConfiguration> + </neonDashlet> + <neonDashlet> + <name>PendingSearchesDashlet</name> + <viewName>SynccontactFilter_view</viewName> + <configName>SynccontactPSFilterViewDashlet</configName> + <uiConfiguration> + <name>uiConfiguration</name> + <xPos v="0" /> + <yPos v="0" /> + <colspan v="2" /> + <rowspan v="4" /> + </uiConfiguration> + </neonDashlet> + </defaultDashlets> +</neonDashboard> diff --git a/neonView/SearchSyncFilter_view/SearchSyncFilter_view.aod b/neonView/SearchSyncFilter_view/SearchSyncFilter_view.aod new file mode 100644 index 0000000000000000000000000000000000000000..6bead95f1d52e019ce2ce7f8b878487d3bfac9f5 --- /dev/null +++ b/neonView/SearchSyncFilter_view/SearchSyncFilter_view.aod @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.8" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.8"> + <name>SearchSyncFilter_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <layout> + <groupLayout> + <name>layout</name> + </groupLayout> + </layout> + <children> + <treeTableViewTemplate> + <name>TreeTable</name> + <favoriteActionGroup1>syncEntryGroup</favoriteActionGroup1> + <defaultGroupFields> + <element>GROUPID</element> + </defaultGroupFields> + <isCreatable v="false" /> + <isDeletable v="false" /> + <isEditable v="false" /> + <columns> + <neonTreeTableColumn> + <name>81a66a66-21dc-415a-8f02-951f352d2f83</name> + <entityField>picture</entityField> + </neonTreeTableColumn> + <neonTreeTableColumn> + <name>ce9fd170-ae02-44db-8919-9387a6f82295</name> + <entityField>DATE_NEW</entityField> + </neonTreeTableColumn> + <neonTreeTableColumn> + <name>f65c136b-6f50-4f0a-b216-06948fb13733</name> + <entityField>GROUPID</entityField> + </neonTreeTableColumn> + <neonTreeTableColumn> + <name>f8084a8b-5721-46f0-a560-b7ba0cd792e9</name> + <entityField>title</entityField> + </neonTreeTableColumn> + <neonTreeTableColumn> + <name>4fabbe10-9579-4cab-b05f-c4c8501f3463</name> + <entityField>synchronized</entityField> + </neonTreeTableColumn> + <neonTreeTableColumn> + <name>a1bfd3cb-9ecd-45bf-8154-ee6faa8ae46a</name> + <entityField>information</entityField> + </neonTreeTableColumn> + </columns> + </treeTableViewTemplate> + </children> +</neonView> diff --git a/neonView/SynccontactCount_view/SynccontactCount_view.aod b/neonView/SynccontactCount_view/SynccontactCount_view.aod new file mode 100644 index 0000000000000000000000000000000000000000..be283a353d741197bbd68f4f25cd51ca71cde926 --- /dev/null +++ b/neonView/SynccontactCount_view/SynccontactCount_view.aod @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.8" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.8"> + <name>SynccontactCount_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <dashletConfigurations> + <neonDashletConfiguration> + <name>SynccontactScoreCardDashlet</name> + <title>Pending datasets</title> + <description>Shows the number of datasets still to be synchronized</description> + <fragment>Synccontact/filter</fragment> + <storeRoles> + <element>INTERNAL_ADMINISTRATOR</element> + </storeRoles> + <icon>VAADIN:FILE_REFRESH</icon> + <categories> + <neonDashletCategory> + <name>Contactsynchronisation</name> + <title>Contact synchronisation</title> + </neonDashletCategory> + </categories> + </neonDashletConfiguration> + </dashletConfigurations> + <layout> + <boxLayout> + <name>layout</name> + </boxLayout> + </layout> + <children> + <scoreCardViewTemplate> + <name>ScoreCard</name> + <fields> + <entityFieldLink> + <name>aae94521-bcb0-40c5-9da9-e2391941f028</name> + <entityField>countDelete</entityField> + </entityFieldLink> + <entityFieldLink> + <name>27855546-c04d-4127-acee-ff261f900432</name> + <entityField>countUpdate</entityField> + </entityFieldLink> + <entityFieldLink> + <name>601ae148-efd1-48ac-8b91-0f6e2569a638</name> + <entityField>countInsert</entityField> + </entityFieldLink> + </fields> + </scoreCardViewTemplate> + <scoreCardViewTemplate> + <name>ScoreCard2</name> + <fields> + <entityFieldLink> + <name>929408b4-44cf-48ab-90aa-792c9b5f6257</name> + <entityField>lastRunSynctable</entityField> + </entityFieldLink> + <entityFieldLink> + <name>df30d561-c1ca-4caf-bdff-cc4a67e7dbb6</name> + <entityField>lastRunOutlook</entityField> + </entityFieldLink> + </fields> + </scoreCardViewTemplate> + </children> +</neonView> diff --git a/neonView/SynccontactFilter_view/SynccontactFilter_view.aod b/neonView/SynccontactFilter_view/SynccontactFilter_view.aod new file mode 100644 index 0000000000000000000000000000000000000000..fd6f541786dfb962afe6a310f76aaf30d10cb212 --- /dev/null +++ b/neonView/SynccontactFilter_view/SynccontactFilter_view.aod @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.8" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.8"> + <name>SynccontactFilter_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <filterable v="true" /> + <dashletConfigurations> + <neonDashletConfiguration> + <name>SynccontactFilterViewDashlet</name> + <title>My synchronized datasets</title> + <description>Shows my synchronized datasets</description> + <fragment>Synccontact/filter</fragment> + <storeRoles /> + <icon>VAADIN:FILE_REFRESH</icon> + <categories> + <neonDashletCategory> + <name>Contactsynchronisation</name> + <title>Contact synchronisation</title> + </neonDashletCategory> + </categories> + <parameters> + <neonDashletParameter> + <name>DataCondition_param</name> + <value>PersonalFilterView</value> + </neonDashletParameter> + </parameters> + </neonDashletConfiguration> + <neonDashletConfiguration> + <name>SynccontactAllFilterViewDashlet</name> + <title>All synchronized datasets</title> + <description>Shows all synchronized datasets</description> + <fragment>Synccontact/filter</fragment> + <storeRoles> + <element>INTERNAL_ADMINISTRATOR</element> + </storeRoles> + <icon>VAADIN:FILE_REFRESH</icon> + <categories> + <neonDashletCategory> + <name>Contactsynchronisation</name> + <title>Contact synchronisation</title> + </neonDashletCategory> + </categories> + <parameters> + <neonDashletParameter> + <name>DataCondition_param</name> + <value>AllFilterView</value> + </neonDashletParameter> + </parameters> + </neonDashletConfiguration> + <neonDashletConfiguration> + <name>SynccontactPSFilterViewDashlet</name> + <title>Pending synchronizations to Outlook</title> + <description>Shows all users which still have a pending synchronization to Outlook</description> + <fragment>Synccontact/filter</fragment> + <storeRoles> + <element>INTERNAL_ADMINISTRATOR</element> + </storeRoles> + <icon>VAADIN:FILE_REFRESH</icon> + <categories> + <neonDashletCategory> + <name>Contactsynchronisation</name> + <title>Contact synchronisation</title> + </neonDashletCategory> + </categories> + <parameters> + <neonDashletParameter> + <name>DataCondition_param</name> + <value>PendingUsersFilterView</value> + </neonDashletParameter> + </parameters> + </neonDashletConfiguration> + </dashletConfigurations> + <layout> + <boxLayout> + <name>layout</name> + </boxLayout> + </layout> + <children> + <tableViewTemplate> + <name>Table</name> + <isCreatable v="false" /> + <isDeletable v="false" /> + <isEditable v="false" /> + <columns> + <neonTableColumn> + <name>c062477b-5fe7-46d7-8237-e68ab5c908e5</name> + <entityField>PICTURE</entityField> + </neonTableColumn> + <neonTableColumn> + <name>c5da3034-4011-4534-b324-daf1f6ca2ddb</name> + <entityField>CONTACT_ID</entityField> + </neonTableColumn> + <neonTableColumn> + <name>653f65d1-1bc0-4dda-aa04-8568950a0ee5</name> + <entityField>contactType</entityField> + </neonTableColumn> + <neonTableColumn> + <name>16fec415-0a9b-476b-b69d-813f5c24eec4</name> + <entityField>STREET_BUILDINGNO</entityField> + </neonTableColumn> + <neonTableColumn> + <name>ac6d672a-23b4-4764-86d5-cd7817fbaa6f</name> + <entityField>ZIP</entityField> + </neonTableColumn> + <neonTableColumn> + <name>eda33ddc-b090-4c8d-ac2c-b3e4945ec3ff</name> + <entityField>CITY</entityField> + </neonTableColumn> + <neonTableColumn> + <name>01360627-7c96-4fc5-9bce-e2c8a038c751</name> + <entityField>COUNTRY</entityField> + </neonTableColumn> + <neonTableColumn> + <name>04f63033-d510-4391-b900-ab532c3fff51</name> + <entityField>EXCHANGEID</entityField> + </neonTableColumn> + <neonTableColumn> + <name>72818bbf-b187-402d-993f-85cb3714da7b</name> + <entityField>UPDATECONTACT</entityField> + </neonTableColumn> + <neonTableColumn> + <name>11702831-fa0d-42bf-a0ee-f2948a67ad8d</name> + <entityField>DATE_DEL</entityField> + </neonTableColumn> + </columns> + </tableViewTemplate> + </children> +</neonView> diff --git a/neonView/SyncedSearchesFilter_view/SyncedSearchesFilter_view.aod b/neonView/SyncedSearchesFilter_view/SyncedSearchesFilter_view.aod new file mode 100644 index 0000000000000000000000000000000000000000..89c647216b629329f1c74bbb775e681f31fe1534 --- /dev/null +++ b/neonView/SyncedSearchesFilter_view/SyncedSearchesFilter_view.aod @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.8" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.8"> + <name>SyncedSearchesFilter_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <filterable v="true" /> + <dashletConfigurations> + <neonDashletConfiguration> + <name>SyncedSearchesTableFilterDashlet</name> + <title>Synchronized searches</title> + <description>Shows all synchronized searches of the users</description> + <fragment>SyncedSearches/filter</fragment> + <storeRoles> + <element>INTERNAL_ADMINISTRATOR</element> + </storeRoles> + <icon>VAADIN:FILE_REFRESH</icon> + <categories> + <neonDashletCategory> + <name>Contactsynchronisation</name> + <title>Contact synchronisation</title> + </neonDashletCategory> + </categories> + </neonDashletConfiguration> + </dashletConfigurations> + <layout> + <noneLayout> + <name>layout</name> + </noneLayout> + </layout> + <children> + <tableViewTemplate> + <name>Table</name> + <favoriteActionGroup1>ExportFilter</favoriteActionGroup1> + <isCreatable v="false" /> + <isDeletable v="false" /> + <isEditable v="false" /> + <columns> + <neonTableColumn> + <name>3b21b438-f1c8-4758-91b4-6a6a80ac3e73</name> + <entityField>USER_ID</entityField> + </neonTableColumn> + <neonTableColumn> + <name>30afaeb1-4445-4c11-856a-e1a03f8c95d6</name> + <entityField>DATE_NEW</entityField> + </neonTableColumn> + <neonTableColumn> + <name>82c23c38-1852-4219-98aa-175bcee71656</name> + <entityField>PROPVAL_CLOB</entityField> + </neonTableColumn> + <neonTableColumn> + <name>f316a0b7-a958-4830-8d70-35bf05eff46c</name> + <entityField>filter</entityField> + </neonTableColumn> + </columns> + </tableViewTemplate> + </children> +</neonView> diff --git a/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod b/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod index 17e0d2bd89d682bbf51d1f299e4d9172000a9a13..63b1cb3ea967792f7d5d066a26efd6c88f0ac9ba 100644 --- a/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod +++ b/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod @@ -222,6 +222,11 @@ <description>Save Location for send Mails. Path is relative to Serverpath</description> <property>/bulkMailFiles/</property> </customStringProperty> + <customIntegerProperty> + <name>ews.syncsize</name> + <description>Defines how big a filter for synchronizing to Outlook may be</description> + <property v="7200" /> + </customIntegerProperty> <customStringProperty> <name>bulkmail.user</name> <description>Title of the useraccount that is used to send bulkmails</description> diff --git a/process/Address_lib/process.js b/process/Address_lib/process.js index bfe22875176dd2d155b1f4b605f58053b02ebd8f..424dace29f423384135c373734119f927436a51a 100644 --- a/process/Address_lib/process.js +++ b/process/Address_lib/process.js @@ -280,13 +280,16 @@ function fetchAddressData( pCondition, pConfig, AddressID, pPerson) break; } } - if (!pPerson) { + if (!pPerson) + { var sqlstr = "select " + fields.join(",") - + " from CONTACT join ORGANISATION on CONTACT.ORGANISATION_ID = ORGANISATION.ORGANISATIONID " + + " from CONTACT " + + " join ORGANISATION on CONTACT.ORGANISATION_ID = ORGANISATION.ORGANISATIONID" + " left join PERSON on CONTACT.PERSON_ID = PERSON.PERSONID " + " left join ADDRESS on CONTACT.ADDRESS_ID = "; - } else { - + } + else + { sqlstr = "select " + fields.join(",") + " from CONTACT join PERSON on CONTACT.PERSON_ID = PERSON.PERSONID " + " left join ORGANISATION on CONTACT.ORGANISATION_ID = ORGANISATION.ORGANISATIONID " @@ -489,24 +492,60 @@ function _getCountryName(pCountryCode) function _formatAddrData( pAddrData, pFormat, pCountry ) { var placeholerInfo = { - "street": {dataPosition: 1}, - "buildingno": {dataPosition: 2}, - "zip": {dataPosition: 3}, - "city": {dataPosition: 4}, - "district": {dataPosition: 8}, - "region": {dataPosition: 9}, - "state": {dataPosition: 10}, - "firstname": {dataPosition: 16}, - "middlename": {dataPosition: 17}, - "lastname": {dataPosition: 18}, - "salutation": {dataPosition: 19}, - "title": {dataPosition: 20}, - "suffix": {dataPosition: 21}, - "country": {dataPosition: 25}, - "country_short": {dataPosition: 5}, - "organisation_name": {dataPosition: 15}, - "salutation_name": {dataPosition: 23}, - "letter_salutation": {dataPosition: 24} + "street": { + dataPosition: 1 + }, + "buildingno": { + dataPosition: 2 + }, + "zip": { + dataPosition: 3 + }, + "city": { + dataPosition: 4 + }, + "district": { + dataPosition: 8 + }, + "region": { + dataPosition: 9 + }, + "state": { + dataPosition: 10 + }, + "firstname": { + dataPosition: 16 + }, + "middlename": { + dataPosition: 17 + }, + "lastname": { + dataPosition: 18 + }, + "salutation": { + dataPosition: 19 + }, + "title": { + dataPosition: 20 + }, + "suffix": { + dataPosition: 21 + }, + "country": { + dataPosition: 25 + }, + "country_short": { + dataPosition: 5 + }, + "organisation_name": { + dataPosition: 15 + }, + "salutation_name": { + dataPosition: 23 + }, + "letter_salutation": { + dataPosition: 24 + } }; var format = pFormat || pAddrData[26];//when no format is given, the default addressformat of the country is used format = _mapFormatPlaceholderTitles(format, pAddrData, pCountry); diff --git a/process/EwsClientSync_lib/EwsClientSync_lib.aod b/process/EwsClientSync_lib/EwsClientSync_lib.aod index a53260007b9ecc486117433576e3c03b8723ff43..a5d86ca9b2d0a6e217449a5b9064ac0bbb153d7a 100644 --- a/process/EwsClientSync_lib/EwsClientSync_lib.aod +++ b/process/EwsClientSync_lib/EwsClientSync_lib.aod @@ -1,6 +1,8 @@ <?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.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.2"> <name>EwsClientSync_lib</name> + <description>old EWS Synchronisation: +for the new ews sync available with version 2021.2.0 the libary EwsSyncContact_lib is used. </description> <majorModelMode>DISTRIBUTED</majorModelMode> <process>%aditoprj%/process/EwsClientSync_lib/process.js</process> <alias>Data_alias</alias> diff --git a/process/EwsClient_lib/process.js b/process/EwsClient_lib/process.js index 51dd088565b42911b3354abcf3b823cf6c1152f1..7fd455c99bd37cd45e420d4db5a618c990a82dc4 100644 --- a/process/EwsClient_lib/process.js +++ b/process/EwsClient_lib/process.js @@ -481,7 +481,6 @@ EwsSyncContactUtils.updateContacts = function(pAliasName, pMailbox, pObjects, do * * @param {String} pAliasName name of the Alias which contains connectiondata * @param {String} pMailbox owner of the contact - * @param {String} pUniqueId defines folder * @param {[[dataArray, adressArray]]} pObjects * @param {boolean} doDebug * @@ -522,16 +521,12 @@ EwsSyncContactUtils.updateContacts = function(pAliasName, pMailbox, pObjects, do * - possible value for "postaladdressindex" * None, Business, Home, Other */ -EwsSyncContactUtils.insertContactsToFolder = function(pAliasName, pMailbox, pUniqueId, pObjects, doDebug) +EwsSyncContactUtils.insertContactsToFolder = function(pAliasName, pMailbox, pObjects, doDebug) { - let taskDescription = $EwsClientTaskDescriptions.INSERT_CONTACT_LIST_TO_FOLDER(); - - let task = <uniqueId>{ - pUniqueId - }</uniqueId> + let taskDescription = $EwsClientTaskDescriptions.INSERT_CONTACT_LIST(); - task += <mailbox>{ + let task = <mailbox>{ pMailbox }</mailbox> @@ -545,7 +540,6 @@ EwsSyncContactUtils.insertContactsToFolder = function(pAliasName, pMailbox, pUni let pluginInput = EwsClientXMLUtils.getRequestXMLforAlias(taskDescription, task, $EwsClientImpersonationModes.SINGLE(), pAliasName); let xmlOutput = EwsClientUtils.callPlugin(pluginInput); - return EwsSyncContactUtils.proceedPluginXmlOutput(xmlOutput, 1, doDebug); } diff --git a/process/EwsSyncContact_lib/EwsSyncContact_lib.aod b/process/EwsSyncContact_lib/EwsSyncContact_lib.aod new file mode 100644 index 0000000000000000000000000000000000000000..01107039afa2016c247f1dc34d191d085e66e34f --- /dev/null +++ b/process/EwsSyncContact_lib/EwsSyncContact_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.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.2"> + <name>EwsSyncContact_lib</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <process>%aditoprj%/process/EwsSyncContact_lib/process.js</process> + <alias>Data_alias</alias> + <variants> + <element>LIBRARY</element> + </variants> +</process> diff --git a/process/EwsSyncContact_lib/process.js b/process/EwsSyncContact_lib/process.js new file mode 100644 index 0000000000000000000000000000000000000000..3e42ff46202d4d4c041a6334cd06f96ac10a0fcd --- /dev/null +++ b/process/EwsSyncContact_lib/process.js @@ -0,0 +1,830 @@ +import("Organisation_lib"); +import("Communication_lib"); +import("system.project"); +import("system.logging"); +import("system.SQLTYPES"); +import("system.swing"); +import("system.tools"); +import("Util_lib"); +import("system.datetime"); +import("system.vars"); +import("system.util"); +import("Address_lib"); +import("system.text"); +import("EwsClient_lib"); +import("Sql_lib"); +import("system.db"); +import("system.vars"); +import("Placeholder_lib"); + + +/** + * Provides methods for handling and interacting with the EWS Plugin + * + * @class + */ +function EwsClientSyncUtils() {} + +/* + * Returns all users, who want to synchronize contacts + */ +EwsClientSyncUtils.getAllExchangeUser = function() +{ + return newSelect("distinct USER_ID") + .from("AB_SYNCCONTACT").arrayColumn(); +} + +/* Existing keys for a exchange contact: + * title, givenname, middlename, surname + * jobtitle, officelocation, department, companyname, manager, assistentname, businesshomepage + * fileasmapping + * messagebody, categories + * id, changekey, lastmodifiedtime, datetimecreated (nur auslesen) + * + * - possible phone numbers: + * AssistantPhone, BusinessFax, BusinessPhone, BusinessPhone2, Callback, CarPhone, CompanyMainPhone, HomeFax, HomePhone, + * HomePhone2, Isdn, MobilePhone, OtherFax, OtherTelephone, Pager, PrimaryPhone, RadioPhone, Telex, TtyTddPhone + * + * - possible email addresses: + * EmailAddress1, EmailAddress2, EmailAddress3 + * + * - possible instant messaging: + * ImAddress1, ImAddress2, ImAddress3 + * + * - possible addresses: + * Business, Home, Other + * - possible values of an address: + * street, postalcode, city, state, countryorregion + * + * postaladdressindex + * - possible values for "postaladdressindex" + * None, Business, Home, Other + */ +EwsClientSyncUtils.getExchangeContactKeyConfig = function(pUserRelationID) +{ + var sqlHelper = new SqlMaskingUtils(); + + //here you can add/remove comments depending on what is needed for the contact in outlook + var placeholders = [ + ["CONTACTID", "fieldname", "CONTACT.CONTACTID"] + , ["EXCHANGEID", "select", newSelect("EXCHANGEID").from("AB_SYNCCONTACT") + .where("AB_SYNCCONTACT.CONTACT_ID = CONTACT.CONTACTID") + .and("AB_SYNCCONTACT.USER_ID", pUserRelationID).toString()] + + // General information + //, ["title", "fieldname", "PERSON.SALUTATION"] + , ["givenname", "fieldname", "PERSON.FIRSTNAME"] + , ["surname", "fieldname", "PERSON.LASTNAME"] + , ["department", "fieldname", "CONTACT.DEPARTMENT"] + , ["jobtitle", "fieldname", "CONTACT.CONTACTROLE"] + , ["position", "fieldname", "CONTACT.CONTACTPOSITION"] + , ["categories", "fieldname", "'Adito_CRM'"] + + // Company name + , ["companyname", "fieldname", "ORGANISATION.NAME"] + + // Company address + , ["Business_street", "select", sqlHelper.concat(["ADDRESS", "BUILDINGNO"])] + , ["Business_city", "select", "CITY"] + , ["Business_postalcode", "select", "ZIP"] + , ["Business_state", "select", "PROVINCE"] + , ["Business_countryorregion", "select", newSelect("NAME_LATIN").from("AB_COUNTRYINFO") + .where("AB_COUNTRYINFO.ISO2 = ADDRESS.COUNTRY").toString()] + + // // Private address + // , ["Home_street", "select", sqlHelper.concat(["(select a2.ADDRESS from ADDRESS a2 where a2.CONTACT_ID = CONTACTID and a2.ADDR_TYPE in (3, 6))", + // "(select a2.BUILDINGNO from ADDRESS a2 where a2.CONTACT_ID = CONTACTID and a2.ADDR_TYPE in (3, 6))"])] + // , ["Home_city", "select", "select a2.CITY from ADDRESS a2 where a2.CONTACT_ID = CONTACTID and a2.ADDR_TYPE in (3, 6)"] + // , ["Home_postalcode", "select", "select a2.ZIP from ADDRESS a2 where a2.CONTACT_ID = CONTACTID and a2.ADDR_TYPE in (3, 6)"] + // , ["Home_state", "select", "select a2.PROVINCE from ADDRESS a2 where a2.CONTACT_ID = CONTACTID and a2.ADDR_TYPE in (3, 6)"] + // , ["Home_countryorregion", "select", "select a2.COUNTRY from ADDRESS a2 where a2.CONTACT_ID = CONTACTID and a2.ADDR_TYPE in (3, 6)"] + // + // // Company contact + , ["EmailAddress1", "select", CommUtil.getStandardSubSqlMail()] + // , ["BusinessFax", "select", "select max(ADDR) from COMMUNICATION where COMMUNICATION.MEDIUM_ID = 'COMMFAX' and ISSTANDARD = '1' and CONTACT_ID = CONTACTID"] + , ["BusinessPhone", "select", EwsClientSyncUtils.getMediumAddrSubsqlByKeyForExchangeSync("COMMPHONE")] + , ["BusinessPhone2", "select", EwsClientSyncUtils.getMediumAddrSubsqlByKeyForExchangeSync("COMMPHONE", "min")] + , ["BusinessHomepage", "select", CommUtil.getMediumAddrSubSqlByKey("COMMINTERNET")] + , ["MobilePhone", "select", EwsClientSyncUtils.getMediumAddrSubsqlByKeyForExchangeSync("COMMMOBIL")] + + //CarPhone will be displayed in Exchange as MobilPhone2 + , ["CarPhone", "select", EwsClientSyncUtils.getMediumAddrSubsqlByKeyForExchangeSync("COMMMOBIL", "min")] + // + // // Private contact + // , ["HomePhone", "function", "getCommAddrTopSQL('Telefon privat', 'CONTACTID', undefined, 'ORDER BY SYNCED')"] + // , ["HomeFax", "function", "getCommAddrTopSQL('Fax privat', 'CONTACTID', undefined, 'ORDER BY SYNCED')"] + // , ["EmailAddress2", "function", "getCommAddrTopSQL('E-Mail privat', 'CONTACTID', undefined, 'ORDER BY SYNCED')"] + // , ["MobilePhone", "function", "getCommAddrTopSQL('Handy', 'CONTACTID', undefined, 'ORDER BY SYNCED')"] + + // , ["fileasmapping", "select", "case when PERS_ID is not null then 'SurnameCommaGivenName' else 'Company' end"] + ]; + + return placeholders.map(function(parameterPlaceholder){ + var type; + + switch(parameterPlaceholder[1]) + { + case "select": + parameterPlaceholder[2] = "(" + parameterPlaceholder[2] + ")"; + type = Placeholder.types.SQLPART; + break; + case "fieldname": + type = Placeholder.types.SQLPART; + break; + default: + throw new Error("Unknown legacy placeholder type"); + + } + + return new Placeholder(parameterPlaceholder[0], type, parameterPlaceholder[2]); + }) +} + + +/* + * The xml-structure, which will be passed to the plugin, may not contain any special characters + * Included social characters must be converted + * + * @param {String} pValue The value which contains special characters + */ +EwsClientSyncUtils.escapeValuesForXML = function(pValue) +{ + + var reps = {}; + reps["&"] = "&"; + reps["\""] = """; + reps["\u201e"] = """; + reps["'"] = "'"; + reps["<"] = "<"; + reps[">"] = ">"; + + pValue = text.replaceAll(pValue, reps).trim(); + + return pValue; +} + +/* + * Assigns the passed header / values to the appropriate objects + * + * @param {String} pHeader Fieldname in exchange + * @param {String} pData Value for header + * @param {Object} pDataObj Object for contact data + * @param {Object} pAddrValueObjBusiness Address object for company address + * @param {Object} pAddrValueObjHome Address object for private address + * @param {Object} pAddrValueObjOther Address object for other address + */ +EwsClientSyncUtils.addDataToValueObjects = function(pHeader, pData, pDataObj, pAddrValueObjBusiness, pAddrValueObjHome, pAddrValueObjOther) +{ + pData = EwsClientSyncUtils.escapeValuesForXML(pData); + // Distinguish address data and contact datas + //var headerNotNull = ["EmailAddress1", "BusinessPhone", "BusinessFax", "BusinessHomepage", "MobilePhone", "HomePhone", "HomeFax", "OtherFax", "EmailAddress2"]; + + if (pHeader.indexOf("Business_") == -1 && pHeader.indexOf("Home_") == -1 && pHeader.indexOf("Other_") == -1) + { + pDataObj[pHeader] = { + "key" : pHeader, + "value" : pData + }; + } + else + { + // Business address + if (pHeader.indexOf("Business") != -1) + { + pHeader = pHeader.replace("Business_", ""); + pAddrValueObjBusiness[pHeader] = { + "key" : pHeader, + "value" : pData + } + } + // Private address + else if (pHeader.indexOf("Home") != -1) + { + pHeader = pHeader.replace("Home_", ""); + pAddrValueObjHome[pHeader] = { + "key" : pHeader, + "value" : pData + } + } + // Other address + else if (pHeader.indexOf("Other") != -1) + { + pHeader = pHeader.replace("Other_", ""); + pAddrValueObjOther[pHeader] = { + "key" : pHeader, + "value" : pData + } + } + } +} + +/* + * Builds the address object for the handing over to the plugin + * + * @param {Object} pAddrObject Address object for the handing over + * @param {Object} pAddrValueObjHome Address object for the private address + * @param {Object} pAddrValueObjBusiness Address object for the company address + * @param {Object} pAddrValueObjOther Address object for ofther address + */ +EwsClientSyncUtils.buildAddrObject = function(pAddrObject, pAddrValueObjHome, pAddrValueObjBusiness, pAddrValueObjOther) +{ + var homeOk = false; + var businessOk = false; + var otherOk = false; + + for each (obj in pAddrValueObjHome) + { + if (obj["value"] != "") + { + homeOk = true; + break; + } + } + for each (obj in pAddrValueObjBusiness) + { + if (obj["value"] != "") + { + businessOk = true; + break; + } + } + for each (obj in pAddrValueObjOther) + { + if (obj["value"] != "") + { + otherOk = true; + break; + } + } + + if (homeOk) + { + pAddrObject["Home"] = { + "addressKey" : "Home", + "value" : pAddrValueObjHome + }; + } + if (businessOk) + { + pAddrObject["Business"] = { + "addressKey" : "Business", + "value" : pAddrValueObjBusiness + }; + } + if (otherOk) + { + pAddrObject["Other"] = { + "addressKey" : "Other", + "value" : pAddrValueObjOther + }; + } +} + +/* + * Deletes all contacts from the synchronization, which are marked for deletion in ADITO + * + * @param {String} pUserID The relation id of the synchronizing user + * @param {String} pMailBox The P.O. box of the synchronizing user + * @param {String} pAlias The exchange-alias, in which the P.O. box is located + * @param {String} pUserLogin The User-Login for debug logging + * @param {String} pDoDebug + * + */ +EwsClientSyncUtils.deleteExchangeContactsForUser = function(pUserID, pMailBox, pAlias, pUserLogin, pDoDebug) +{ + + // Delete all at the first import wich are marked 'DATE_DEL' + var delContacts = newSelect("EXCHANGEID") + .from("AB_SYNCCONTACT") + .where("AB_SYNCCONTACT.USER_ID", pUserID) + .and("AB_SYNCCONTACT.DATE_DEL is not null") + .and("AB_SYNCCONTACT.EXCHANGEID is not null") + .arrayColumn(); + + var deletedItems = []; + try + { + var exchangeids = EwsSyncContactUtils.deleteContactByID(pAlias, delContacts, pMailBox, pDoDebug); + } + catch(ex) + { + var msg = "Error while calling the plugin: " + logging.toLogString(ex.rhinoException != undefined ? ex.rhinoException : ex, true); + EwsClientSyncUtils.createLogEntry(pUserLogin, "EwsSyncToExchange", msg.substring(0, 5000), "HIGH"); + } + + while (exchangeids[0].length > 0) + { + let exchangeidsPart = exchangeids[0].splice(0, 30);//max limit bis jetzt 30 + db.deleteData("AB_SYNCCONTACT", "DATE_DEL is not null and USER_ID = '" + pUserID + "' and EXCHANGEID in (BINARY '" + exchangeidsPart.join("', BINARY '") + "')", "Data_alias", 300000); + deletedItems = deletedItems.concat(exchangeidsPart); + } + var notFoundItems = []; + var errorItems = []; + + while (exchangeids[1].length > 0) + { + var deletes = []; + + let exchangeidsPart = exchangeids[1].splice(0, 30);//max limit bis jetzt 30 + + for (let i = 0; i < exchangeidsPart.length; i++) + { + if(exchangeidsPart[i][3] == "ErrorItemNotFound") + { + deletes.push(exchangeidsPart[i][0]); + notFoundItems.push(exchangeidsPart[i][0], pUserID); + } + else + { + errorItems.push(exchangeidsPart[i][0] , pUserID); + } + } + if(deletes.length > 0) + { + db.deleteData("AB_SYNCCONTACT", " EXCHANGEID in (BINARY '" + deletes.join("', BINARY '") + "') and USER_ID = '" + pUserID + "'", "Data_alias", 300000); + deletedItems = deletedItems.concat(deletes); + } + } + + if(pDoDebug && notFoundItems.length > 0) + { + logging.log("EWSSYnc not found items: " + notFoundItems.toSource()); + } + if(pDoDebug && errorItems.length > 0) + { + logging.log("EWSSYnc error items: " + errorItems.toSource()); + } + if(pDoDebug && deletedItems.length > 0) + { + logging.log("EWSSYnc deletedItems items: " + deletedItems.toSource()); + } +} + +/* + * Inserts new sync contacts into the exchange-folder of the synchronizing user + * + * @param {String} pUserID The relation id of the synchronizing user + * @param {String} pMailBox The P.O. box of the synchronizing user + * @param {String} pAlias The exchange-alias, in which the p.o. box is located + * @param {String} pUserLogin The User-Login for debug logging + * @param {String} pDoDebug + * + */ +EwsClientSyncUtils.insertExchangeContactsForUser = function(pUserID, pMailBox, pAlias, pUserLogin, pDoDebug) +{ + var contactsForInsSQL = newSelect("CONTACT_ID") + .from("AB_SYNCCONTACT") + .where("AB_SYNCCONTACT.EXCHANGEID is null") + .and("AB_SYNCCONTACT.USER_ID", pUserID).arrayColumn(); + + if (contactsForInsSQL.length > 0) + { + + var config = EwsClientSyncUtils.getExchangeContactKeyConfig(pUserID); + + var addressDataCond = "CONTACT.CONTACTID in (select CONTACT_ID " + + "from AB_SYNCCONTACT where EXCHANGEID is null and USER_ID = '" + pUserID + "')";//set a string condition for performance + var data = getAddressData(addressDataCond, config, undefined, false); + var header = []; + // Data has column definitions on the first position -> Collect them + for (let i = 0; i < data[0].length; i++) + { + header.push(data[0][i].replace(new RegExp("[{@}]","g"), "")); + } + + var dataObj; + var addrObj; + var objects = []; + var addrValueObjHome = {}; + var addrValueObjBusiness = {}; + var addrValueObjOther = {}; + // Go thorugh array from index 1 again, the header has been collected before + for (let i = 1; i < data.length; i++) + { + dataObj = new Object(); + addrObj = new Object(); + addrValueObjBusiness = {}; + addrValueObjHome = {}; + addrValueObjOther = {}; + + // The address data gets assigned to the respective object + for (let j = 0; j < header.length; j++) + { + EwsClientSyncUtils.addDataToValueObjects(header[j], data[i][j], dataObj, addrValueObjBusiness, addrValueObjHome, addrValueObjOther); + } + + EwsClientSyncUtils.buildAddrObject(addrObj, addrValueObjHome, addrValueObjBusiness, addrValueObjOther); + objects.push([dataObj, addrObj]); + } + + // Insert person via plugin call and save generated exchange id + try + { + while (objects.length > 0) + { + let objectPart = objects.splice(0, 200);//max limit bis jetzt 200 + var exchangeids = EwsSyncContactUtils.insertContactsToFolder(pAlias, pMailBox, objectPart, pDoDebug); + + while (exchangeids[0].length > 0) + { + let exchangeidsPart = exchangeids[0].splice(0, 30);//max limit bis jetzt 30 + EwsClientSyncUtils.updateADITOContactsAfterAction(exchangeidsPart, pUserID); + } + } + } + catch(ex) + { + var msg = "Error while calling the plugin: " + logging.toLogString(ex.rhinoException != undefined ? ex.rhinoException : ex, true); + EwsClientSyncUtils.createLogEntry(pUserLogin, "EwsSyncToExchange", msg.substring(0, 5000), "HIGH"); + } + } +} + +/* + * All ADITO-contacts of an user will be synchronized to exchange if the edit-date is higher than the last import run + * If the user can'be found in exchange, then it will also be deleted on ADITO + * + * @param {String} pUserID RelationID of the synchronizing user + * @param {String} pMailBox The P.O. box of the synchronizing user + * @param {String} pAlias The exchange-alias, in which the p.o. box is located + * @param {String} pUserLogin The User-Login for debug logging + * @param {String} pDoDebug + * + * @returns {void} + */ +EwsClientSyncUtils.updateExchangeContactsForUser = function(pUserID, pMailBox, pAlias, pUserLogin, pDoDebug) +{ + // Fetch updateable contacts from the user + var contactsForUpdSQL = newSelect("CONTACT_ID") + .from("AB_SYNCCONTACT") + .where("AB_SYNCCONTACT.EXCHANGEID is not null") + .and("AB_SYNCCONTACT.USER_ID", pUserID) + .and("AB_SYNCCONTACT.UPDATECONTACT", "1") + .arrayColumn(); + + if (contactsForUpdSQL.length > 0) + { + // Get data with config + var config = EwsClientSyncUtils.getExchangeContactKeyConfig(pUserID); + var addressDataCond = "CONTACT.CONTACTID in (select CONTACT_ID from AB_SYNCCONTACT " + + " where EXCHANGEID is not null and USER_ID = '" + pUserID + "' and UPDATECONTACT = '1')";//set a string condition for performance + + var data = getAddressData(addressDataCond, config, undefined, false); + // Data has a column description on the first position + // collect those and use it below as keys for the userData-object + var header = []; + // Data has column definitions on the first position -> Collect them + for (let i = 0; i < data[0].length; i++) + { + header.push(data[0][i].replace(new RegExp("[{@}]","g"), "")); + } + + var dataObj; + var addrObj; + var addrValueObjBusiness; + var addrValueObjHome; + var addrValueObjOther; + var exchangeid; + var objects = []; + // Go thorugh array from index 1 again, the header has been collected before + for (let i = 1; i < data.length; i++) + { + dataObj = new Object(); + addrObj = new Object(); + addrValueObjBusiness = {}; + addrValueObjHome = {}; + addrValueObjOther = {}; + + // The address data are assigned to the respective object based on the tags(Business_, Home_, Other_) + // header.length == data[i].length + for (let j = 0; j < header.length; j++) + { + EwsClientSyncUtils.addDataToValueObjects(header[j], data[i][j], dataObj, addrValueObjBusiness, addrValueObjHome, addrValueObjOther); + } + + // The address-object which will be passed, is created from the filled object + EwsClientSyncUtils.buildAddrObject(addrObj, addrValueObjHome, addrValueObjBusiness, addrValueObjOther); + + // Get the exchangeID from the data-object for the update + exchangeid = dataObj["EXCHANGEID"].value; + objects.push([exchangeid, dataObj, addrObj]); + } + // Update contact in exchange via plugin call + + var notFoundItems = []; + var errorItems = []; + var updatedItems = []; + var deletedItems = []; + + while (objects.length > 0) + { + let objectsPart = objects.splice(0, 200);//max limit until now is 200 + + try + { + var exchangeids = EwsSyncContactUtils.updateContacts(pAlias, pMailBox, objectsPart, pDoDebug) + } + catch(ex) + { + var msg = "Error while calling the plugin: " + logging.toLogString(ex.rhinoException != undefined ? ex.rhinoException : ex, true); + EwsClientSyncUtils.createLogEntry(pUserLogin, "EwsSyncToExchange", msg.substring(0, 5000), "HIGH"); + } + + while (exchangeids[0].length > 0) + { + let exchangeidsPart = exchangeids[0].splice(0, 30);//max limit bis jetzt 30 + db.updateData("AB_SYNCCONTACT", ["UPDATECONTACT"], null, ['0'], + " EXCHANGEID in (BINARY '" + exchangeidsPart.join("', BINARY '") + "') and USER_ID = '" + pUserID + "'", "Data_alias", 300000); + updatedItems = updatedItems.concat(exchangeidsPart); + } + while (exchangeids[1].length > 0) + { + var deletes = []; + + let exchangeidsPart = exchangeids[1].splice(0, 30);///max limit until now is 30 + + for (let i = 0; i < exchangeidsPart.length; i++) + { + if(exchangeidsPart[i][3] == "ErrorItemNotFound") + { + deletes.push(exchangeidsPart[i][0]); + notFoundItems.push(exchangeidsPart[i][0] , pUserID); + } + else + { + errorItems.push(exchangeidsPart[i].toSource(), pUserID); + } + } + if(deletes.length > 0) + { + db.deleteData("AB_SYNCCONTACT", " EXCHANGEID in (BINARY '" + deletes.join("', BINARY '") + "') and USER_ID = '" + pUserID + "'", "Data_alias", 300000); + deletedItems = deletedItems.concat(deletes); + } + + } + } + + if(pDoDebug && notFoundItems.length > 0) + { + logging.log("EWSSYnc not found items: " + notFoundItems.toSource()); + } + if(pDoDebug && errorItems.length > 0) + { + logging.log("EWSSYnc error items: " + errorItems.toSource()); + } + if(pDoDebug && deletedItems.length > 0) + { + logging.log("EWSSYnc deleted items: " + deletedItems.toSource()); + } + if(pDoDebug && updatedItems.length > 0) + { + logging.log("EWSSYnc updated items: " + updatedItems.toSource()); + } + } +} + +/* + * Updates the Edit-Date and the exchangeID into the associated data set of AB_SYNCCONTACT + * If the ExchangeID isn't passed, then it will just update DATE_EDIT + * + * @param {Array<Array>} pUpdateValues 2d-array in the following form: [[CONTACTID, zugehörige neue EXCHANGEID]] + * @param {String} pUserID ID of the correspnding user + */ +EwsClientSyncUtils.updateADITOContactsAfterAction = function(pUpdateValues, pUserID) +{ + var cols = ["EXCHANGEID"]; + var vals; + var cond = ""; + var updArr = []; + for (let i = 0; i < pUpdateValues.length; i++) + { + vals = []; + // Get EXCHANGEID + if (pUpdateValues[i][1]) + { + vals.push(pUpdateValues[i][1]); + } + + cond = "CONTACT_ID = '" + pUpdateValues[i][0] + "' and USER_ID = '" + pUserID + "'"; + updArr.push(["AB_SYNCCONTACT", cols, null, vals, cond]); + } + db.updates(updArr, db.getCurrentAlias(), 300000); +} + +/* + * creates a log-entry for the Ews-sync + * + * @param {String} pUserId userid of the log + * @param {String} pType the type of the log + * @param {String} pInfo additional info + * @param {String} pPriority prio of the log + * + * @return {void} + */ +EwsClientSyncUtils.createLogEntry = function(pUserId, pType, pInfo, pPriority) +{ + db.insertData("EWS_INFO_LOG" + , ["EWS_INFO_LOGID", "DATE_NEW", "USER_ID", "TYPE", "INFO", "PRIORITY"] + , null + , [util.getNewUUID(), vars.get("$sys.date"), (pUserId || ""), pType, pInfo, pPriority] + , "Data_alias"); +} + + +/* + * deletes unnecessary Data for the Ews-sync + * + * @return {void} + */ +EwsClientSyncUtils.manageUnnecessaryData = function() +{ + db.deleteData("AB_SYNCCONTACT", "EXCHANGEID is null and DATE_DEL is not null", "Data_alias", 300000);//delete unecessary syncs + + var userNames = newSelect("asys_users.NAME", SqlUtils.getSystemAlias()) + .from("asys_users") + .where( "asys_users.PROPVAL", true, SqlBuilder.NOT_EQUAL()) + .and("asys_users.PROPKEY", 'isActive').arrayColumn(); + + while (userNames.length > 0) + { + let userNamesPart = userNames.splice(0, 500); + + newWhere("AB_SYNCCONTACT.USER_ID", userNamesPart, SqlBuilder.IN(), null, "Data_alias") + .updateData(true, "AB_SYNCCONTACT", ["DATE_DEL"], null, [vars.get("$sys.date")], 300000); + //if there are Users whitch are inactive: delete the Syncs + } +} + +/* + * creates a log-entry for the Ews-sync + * + * @param {Object} pUserMapping mapping with the users [ASYS_USERS.PROPVAL, ASYS_USERS.NAME, CONTACTID] + * @param {Object} pUserLoginPropval data array with the users [ASYS_USERS.PROPVAL, ASYS_USERS.NAME, PERSON.ORIGINAL_CONTACTID] + * @param {Object} pStoredSearchMapping mapping with the stored searches [ASYS_USERS.PROPVAL, ASYS_USERS.PROPVAL_CLOB, ASYS_USERS.GROUPID, ASYS_USERS.NAME] + * + * @return {void} + */ +EwsClientSyncUtils.updateEntrysInSyncTable = function(pUserMapping, pUserLoginPropval, pStoredSearchMapping) +{ + var updateInformation = []; + var maxSyncsize = project.getPreferenceValue("custom.ews.syncsize", EwsClientSyncUtils.getMaxSyncSize()); + + for each(let [pPropval, pName] in pUserLoginPropval) //for every user + { + try + { + var sqlStringForDelete = newWhere("1 = 1"); + var tempUserMapping = pUserMapping[pName]; + var userStoredSearches = pStoredSearchMapping[tempUserMapping[0]]; + var maskingUtils = new SqlMaskingUtils(); + if(userStoredSearches != undefined && tempUserMapping.length > 1)//if the user has stored searches + { + for each( let [pPropvalClob, pGroupId, pID, pPropvalSearchSync] in userStoredSearches)//for every stored search + { + var type = pGroupId; + type = type.substring(7, type.length - 6);//get entity name + //---- + var search = JSON.parse(pPropvalClob)["search"]; // search part of the filter JSON + var whereCond = db.toFilterCondition(JSON.stringify(search), type); + //-------------------------------------------------------------------------- + var sqlString = new SqlBuilder().selectDistinct("CONTACT.CONTACTID") + .from("CONTACT") + .whereIfSet(whereCond); + + if(type == 'Person_entity') + { + sqlString.join("PERSON", "CONTACT.PERSON_ID = PERSON.PERSONID") + .join("ORGANISATION", "ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID"); + } + else + { + sqlString.join("ORGANISATION", newWhere("ORGANISATION.ORGANISATIONID = CONTACT.ORGANISATION_ID") + .and("CONTACT.PERSON_ID is null").and("CONTACT.CONTACTID", OrgUtils.getPrivateOrganisationId(), SqlBuilder.NOT_EQUAL()) + .and("CONTACT.CONTACTID", OrgUtils.getDSGVOAnonymisierungsOrganisationId(), SqlBuilder.NOT_EQUAL())); + } + + sqlString.leftJoin("ADDRESS", "ADDRESS.ADDRESSID = CONTACT.ADDRESS_ID"); + + try + { + sqlStringForDelete.and("AB_SYNCCONTACT.CONTACT_ID", sqlString, SqlBuilder.NOT_IN()); + + var insertSql = sqlString.copy(); + var searchSql = sqlString.arrayColumn(); + + if(searchSql.length <= maxSyncsize)//here you can set a limit for the maximum Sync + { + insertSql.select("distinct " + maskingUtils.newUUID() + ", " + maskingUtils.currentTimestamp() + ", '" + tempUserMapping[1] + "', CONTACTID") + .leftJoin("AB_SYNCCONTACT", newWhere("AB_SYNCCONTACT.USER_ID", tempUserMapping[1]).and("AB_SYNCCONTACT.CONTACT_ID = CONTACT.CONTACTID")) + .and("AB_SYNCCONTACT.SYNCCONTACTID IS NULL") + .groupBy("CONTACT.CONTACTID"); + + db.table("INSERT INTO AB_SYNCCONTACT (SYNCCONTACTID, DATE_NEW, USER_ID, CONTACT_ID) " + + insertSql.toString());//the SQLBuilder does not provide a function for INSERT INTO + + if(pPropvalSearchSync) + { + updateInformation.push(["ASYS_USERS", ["PROPVAL_CLOB"], null, + [""], "ASYS_USERS.ID = '" + pID + "'", SqlUtils.getBinariesAlias()]); + } + } + else + { + if(!pPropvalSearchSync) + { + updateInformation.push(["ASYS_USERS", ["PROPVAL_CLOB"], null, + ["Search greater %0, sync. not possible"], "ASYS_USERS.ID = '" + pID + "'", SqlUtils.getBinariesAlias()]); + } + } + } + catch(ex) + { + EwsClientSyncUtils.createLogEntry(pPropval, "EWSContactSync", "An error occured while trying run a Stored search which inserts values in the Synctable! \n" + + "Statement of the damaged filter select: \n" + + sqlString.toString().substring(0, 5000), "HIGH"); + } + } + } + //the deletion is actually an update where the DATE_DEL column is set. The sync process will then automatically delete this record + new SqlBuilder("Data_alias") + .where("AB_SYNCCONTACT.USER_ID", tempUserMapping[1]) + .and(sqlStringForDelete) + .updateData(true, "AB_SYNCCONTACT", ["DATE_DEL"], null, [vars.get("$sys.date")], 300000); + } + catch(e) + { + EwsClientSyncUtils.createLogEntry(pPropval, "EWSContactSync", + logging.toLogString(e.rhinoException != undefined ? e.rhinoException : e, true).substring(0, 5000), "HIGH"); + } + } + + while (updateInformation.length > 0)//set the information to the Syncs if a Search is greater than 7200 + { + let updateInformationPart = updateInformation.splice(0, 30);//max limit bis jetzt 30 + db.updates(updateInformationPart, SqlUtils.getBinariesAlias(), 300000); + } +} + +/* + * returns a max/min Subsql for the passed CommMedium like (COMMPHONE, COMMMOBILE, .. ) <br> + * used mainly by the Exchange Sync, because here we can have exactly 2 addresses.<br> + * + * @param {String} pCommMedium <p> + * MediumID that determines for which medium the sql will be returned<br> + * + * @param {String} pMode <p> controlls if max(Addr) or min(Addr) will be used, default value is max.<br> + * Possible values are "min" and "max" + * @return {String} <p> + * + * Subsql as a String which resolves the Communication Addr for the contact<br> + */ + +EwsClientSyncUtils.getMediumAddrSubsqlByKeyForExchangeSync = function(pCommMedium, pMode) +{ + var addrSql; + + if(pMode == undefined) + { + pMode = "max"; + } + + pMode = pMode.toLowerCase(); + + if(pMode == "min") + { + var countCommSql = newSelect("count(COMMUNICATION.ADDR)") + .from("COMMUNICATION") + .where("COMMUNICATION.OBJECT_ROWID = CONTACT.CONTACTID") + .and("COMMUNICATION.MEDIUM_ID", pCommMedium); + + var commSql = newSelect("min(COMMUNICATION.ADDR)") + .from("COMMUNICATION") + .where("COMMUNICATION.OBJECT_ROWID = CONTACT.CONTACTID") + .and("COMMUNICATION.MEDIUM_ID", pCommMedium) + + //when only one communication address is set (for that medium) + //a min('Addr') would return the same value as the max('Addr') selection + addrSql = SqlBuilder.caseStatement() + .when(countCommSql, "1" ,SqlBuilder.GREATER(), SQLTYPES.INTEGER) + .then(commSql) + } + else + { + addrSql = newSelect("max(COMMUNICATION.ADDR)") + .from("COMMUNICATION") + .where("COMMUNICATION.OBJECT_ROWID = CONTACT.CONTACTID") + .and("COMMUNICATION.MEDIUM_ID", pCommMedium); + } + + return addrSql.toString(); +} + +/* + * returns the recommended max ews sync size + * + * @return {Number} max Syncsize + */ +EwsClientSyncUtils.getMaxSyncSize = function() +{ + return 7200; +} \ No newline at end of file diff --git a/process/EwsSyncContact_serverProcess/EwsSyncContact_serverProcess.aod b/process/EwsSyncContact_serverProcess/EwsSyncContact_serverProcess.aod new file mode 100644 index 0000000000000000000000000000000000000000..f351f78da94b26cf65b32aa15440f426a96cfef8 --- /dev/null +++ b/process/EwsSyncContact_serverProcess/EwsSyncContact_serverProcess.aod @@ -0,0 +1,12 @@ +<?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.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.2"> + <name>EwsSyncContact_serverProcess</name> + <title>EWS - Manage Synctable</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <documentation>%aditoprj%/process/EwsSyncContact_serverProcess/documentation.adoc</documentation> + <process>%aditoprj%/process/EwsSyncContact_serverProcess/process.js</process> + <alias>Data_alias</alias> + <variants> + <element>EXECUTABLE</element> + </variants> +</process> diff --git a/process/EwsSyncContact_serverProcess/documentation.adoc b/process/EwsSyncContact_serverProcess/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..cb0ba53f805295528700111121108b1623fb0432 --- /dev/null +++ b/process/EwsSyncContact_serverProcess/documentation.adoc @@ -0,0 +1,154 @@ +:toc2: left +:numbered: +:hardbreaks: + +== EwsSyncContact_serverProcess + +*The process uses the EwsSyncContact_lib* + +=== Purpose of this Process +In order to prepare the synchronisation for the contacts a process called "EwsSyncContact_serverProcess" +must be running. +In the client I can save searches and share them for synchronization to outlook. +This process in each run matches changes to the filters for each user and deletes/updates/inserts +the contacts found in the filter into the AB_SYNCCONTACT table. + +[NOTE] +Be careful when using a PostgreSQL database. The process executes a function +called EwsClientSyncUtils.updateEntrysInSyncTable() which executes a SQL +that uses the function maskingUtils.newUUID(). PostgreSQL needs a module called "uuid-ossp" to generate this UUID. + +*For example: A user synchronizes all contacts with the LASTNAME "mustermann"* + +=== Inserting contacts +If a user creates a new contact with the LASTNAME "mustermann" the contact will be automatically inserted by the process. + +=== Updating contacts +If a user updates a contact with the LASTNAME "mustermann" the audit process will update the +column UPDATECONTACT for the entries in the table AB_SYNCCONTACT too. + +In the process_audit process a function called AuditUpdateSyncEntries() is responsible for it. +This function contains the variable "affectedDB" in which you can +define when the process_audit changes entries in the AB_SYNCCONTACT. +[NOTE] +*Standard configuration:* + "CONTACT": ["DEPARTMENT", "CONTACTROLE", "CONTACTPOSITION"], + "ORGANISATION": ["NAME"], + "ADDRESS": ["ZIP", "ADDRESS", "BUILDINGNO", "COUNTRY", "CITY", "PROVINCE", "ADDR_TYPE"], + "PERSON": ["FIRSTNAME", "LASTNAME"], + "COMMUNICATION": ["ADDR", "MEDIUM_ID", "ISSTANDARD"] + --- +If the column DEPARTMENT in CONTACT will be changed an update will be executed. +If the column STATUS in CONTACT will be changed no update will be executed. + +=== Deleting contacts +If a user deletes a contact with the LASTNAME "mustermann" the contact will be automatically deleted by the process. + +== EwsSyncToExchange_serverProcess + +*The process uses the EwsSyncContact_lib and the EwsClientSync_lib* + +=== Purpose of this Process +This process is meant to sync ADITO contacts and organisations with the configured Exchange of the Project. +Synced things are Informations that belong to a Person/Organisation +For example: +- Firstname +- Lastname +- Address +- Communication like phone / mobil / email / Homepage/ fax etc. +- Organisation Name + +In the basic variant of the Contact sync only syncs to Exchange there's no writing data back to ADITO. +So if a dataset gets a change in exchange - for example changing the phonenumber - this change would not be written back to ADITO. +When then a change appears to that specific dataset in ADITO the Contact will be synced again and will overwrite the changes made in exchange. + +=== Requirements +In order for syncing Contacts to Exchange there are some requirements needed. +First of all there has to be an exchange Alias with a correct configuration. + +[NOTE] +The Ews-Client Plugin needs an Impersonationuser! Ensure that it is correct set. +With the AuthMethod OAuth2 there is no Possibillity to set the Imperso User yet. +In order to configure the Impersouser anyway, change the AuthMethod to default. +Now you can edit the details for the Impersonation User. After your changes simply change +the AuthMethod to OAuth2 back. + +The process currently uses the Exchange alias "Exchange_devIntern". +Here the configured Exchange must be specified in the process, which is also +used for the user to synchronize. + +A maximum synchronization limit must be specified in the PREFERENCES_PROJECT. In the custom preferences there must be an entry "ews.syncsize". If this is not specified, 7200 is used by default. This parameter prevents too many contacts per filter from reaching outlook. + +The basic version of this process don't needs a specific folder to sync the Contacts in. +Per default the process addresses the default contact folder. +In order to distinguish the contacts from the contacts created in outlook, +a category "Adito_CRM" is specified for the contact. + +If the processes are configured in the manager, a user must be specified in addition to the "Timer type = TIMERTYPE_SERVER", so that the function which evaluates the synchronization filters in the background (db.toFilterCondition) works! +In the Dreso project, very good experiences were made with the following intervals +-> EWS - Manage Synctable: 45 min. +-> EWS - Sync to Exchange: 30 min. + +=== Debugging +In generally the Process will return Information in it's process History if something wents wrong. + +You can see it with the ADITO manger in the Process History Area or +you check the database table EWS_INFO_LOG. Every activity of the process is logged in this table. + +For manual extended debugging the Process you can just activate the Debug variable at the begin of the process. +After activating it, you'll see logs for each user and the processed data. + + +=== Process +The following will describe the functions and the functionality of the process + +==== EWSdeleteContactsForUser +Removes those Contacts in Exchange for the current user in the Process which has set an DATE_DEL Date. +The Entry gets also deleted out of the synccontact Table. + +When the debug parameter was enabled you'll also get more information which contact was successfully deleted and which not. + +==== EWSupdateContactsForUser +In that Function all that Contacts which had been recently updated getting synchronized. + +If a change in contact dataset appears, the process_audit will notice it and call +a function for updating the DATE_EDIT column and the UPDATECONTACT column to 1 in the AB_SYNCCONTACT table. + +The process will handle those, where the UPDATECONTACT column is set to 1. + +==== EWSinsertContactsForUser +This function will synchronize all new Contacts marked for sync for the current User in the batch. +By default a limit of max. 7200 contacts which can be synchronized per filter is possible +so that the performance of the process is not overloaded and the outlook profile is not flooded with contacts. + +After the first run the unique ID gets returned by exchange, we update the matching entry in the ab_synccontact table. +In order to identify each contact later again. The ID usually also contains the encoded folder destination. +BE CAREFUL: The Exchange id is case sensitive. That means Bx234967Elbn != BX234967ELBN. + + +== Important note +Sometimes it can happen that if too many contacts are created in a short time in outlook +for a user, exchange rejects the query. therefore we always send small blocks of 200. +If the exchange rejects the query we get the error +*The server cannot service this request right now. Try again later* +This is not fatal. The next time we send the package again until all contacts are in outlook. + +*BUT: We always send 200 packets of contacts to outlook and get the EXCHANGEID of the contacts as return. +If the server is restarted and we are waiting for the return from outlook, +it can happen that contacts are created twice in outlook, because we have not yet recorded the EXCHANGEID in ADITO. +The process should therefore be switched off before a planned restart* + +== Deprecated functions of the old EWS Sync + +===addToContactSync & removeFromContactSync +These actions in the Person_entity are outdated and where set to invisible. + +===ewsSyncContacts_serverProcess +The whole process is outdated. +New process for this: *EwsSyncContact_serverProcess* + +===EwsClientSync_lib +The whole library provides the functions for the EWS favorites logic and is therefore outdated. +New library for this: *EwsSyncContact_lib* + +These processes will still be included in the release of the EWS, but will be dropped at some point later on. \ No newline at end of file diff --git a/process/EwsSyncContact_serverProcess/process.js b/process/EwsSyncContact_serverProcess/process.js new file mode 100644 index 0000000000000000000000000000000000000000..44c61861a623459ee65f3702c16c09a8f7ef1f08 --- /dev/null +++ b/process/EwsSyncContact_serverProcess/process.js @@ -0,0 +1,64 @@ +import("EwsSyncContact_lib"); +import("system.datetime"); +import("system.vars"); +import("Sql_lib"); +import("system.db"); + +var maskingUtils = new SqlMaskingUtils(); + +//get all active usertitles and usernames +var userLoginPropval = newSelect(["ASYS_USERS.PROPVAL", "ASYS_USERS.NAME"], SqlUtils.getSystemAlias()) +.from("ASYS_USERS") +.join("ASYS_USERS", "innerUser.NAME = ASYS_USERS.NAME", "innerUser") +.where(["ASYS_USERS", "PROPVAL", "innerUser"], "true") +.and(["ASYS_USERS", "PROPKEY", "innerUser"], "isActive") +.and("ASYS_USERS.PROPKEY", "title") +.table(); + +var userMapping = []; +var storedSearchMapping = []; + +userLoginPropval.forEach(function([pPropval, pName]) +{ + if(userMapping[pName] == undefined) + { + userMapping[pName] = [pPropval, pName];//userLoginPropval[NAME] = PROPVAL, NAME + } +});//mapping + +//if a filter has been deleted in the meantime we have to delete the sync entry as well +newWhere("ASYS_USERS.ID", + newSelect("ASYS_USERS.ID", SqlUtils.getSystemAlias()) + .from("ASYS_USERS") + .leftJoin("ASYS_USERS", "filterUser.ID = ASYS_USERS.PROPVAL", "filterUser") + .where("ASYS_USERS.PROPKEY", "SearchSync") + .and("filterUser.ID is null") + , undefined, undefined, SqlUtils.getSystemAlias()) +.deleteData(true, "ASYS_USERS", 300000); + +//get all user stored searches which will be synced +var storedSearches = newSelect(["innerUser.PROPVAL", "filterUser.PROPVAL_CLOB", "ASYS_USERS.GROUPID", "ASYS_USERS.NAME", "ASYS_USERS.ID", "ASYS_USERS.PROPVAL_CLOB"], SqlUtils.getSystemAlias()) + .from("ASYS_USERS") + .join("ASYS_USERS", "innerUser.NAME = ASYS_USERS.NAME and innerUser.PROPKEY = 'title'", "innerUser") + .join("ASYS_USERS", "filterUser.ID = ASYS_USERS.PROPVAL", "filterUser") + .where("ASYS_USERS.PROPKEY", "SearchSync") + .table(); + + +storedSearches.forEach(function([pPropvalTitle, pPropvalClob, pGroupId, pName, pID, pPropvalSearchSync]) +{ + if(storedSearchMapping[pPropvalTitle] == undefined) + { + storedSearchMapping[pPropvalTitle] = [[pPropvalClob, pGroupId, pID, pPropvalSearchSync]]; + } + else + { + storedSearchMapping[pPropvalTitle].push([pPropvalClob, pGroupId, pID, pPropvalSearchSync]); + } +});//mapping + +EwsClientSyncUtils.updateEntrysInSyncTable(userMapping, userLoginPropval, storedSearchMapping); + +EwsClientSyncUtils.manageUnnecessaryData(); + +EwsClientSyncUtils.createLogEntry("", "EWSContactSync", "Finished", "LOW"); \ No newline at end of file diff --git a/process/EwsSyncToExchange_serverProcess/EwsSyncToExchange_serverProcess.aod b/process/EwsSyncToExchange_serverProcess/EwsSyncToExchange_serverProcess.aod new file mode 100644 index 0000000000000000000000000000000000000000..b3da98816ffec65e99f1bff08899d90f59c3a1f0 --- /dev/null +++ b/process/EwsSyncToExchange_serverProcess/EwsSyncToExchange_serverProcess.aod @@ -0,0 +1,12 @@ +<?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.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.2"> + <name>EwsSyncToExchange_serverProcess</name> + <title>EWS - Sync to Exchange</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <documentation>%aditoprj%/process/EwsSyncToExchange_serverProcess/documentation.adoc</documentation> + <process>%aditoprj%/process/EwsSyncToExchange_serverProcess/process.js</process> + <alias>Data_alias</alias> + <variants> + <element>EXECUTABLE</element> + </variants> +</process> diff --git a/process/EwsSyncToExchange_serverProcess/documentation.adoc b/process/EwsSyncToExchange_serverProcess/documentation.adoc new file mode 100644 index 0000000000000000000000000000000000000000..20744690c5f3df3a1770b2ff4cbcda0c78ec72f0 --- /dev/null +++ b/process/EwsSyncToExchange_serverProcess/documentation.adoc @@ -0,0 +1,155 @@ +:toc2: left +:numbered: +:hardbreaks: + +== EwsSyncContact_serverProcess + +*The process uses the EwsSyncContact_lib* + +=== Purpose of this Process +In order to prepare the synchronisation for the contacts a process called "EwsSyncContact_serverProcess" +must be running. +In the client I can save searches and share them for synchronization to outlook. +This process in each run matches changes to the filters for each user and deletes/updates/inserts +the contacts found in the filter into the AB_SYNCCONTACT table. + +[NOTE] +Be careful when using a PostgreSQL database. The process executes a function +called EwsClientSyncUtils.updateEntrysInSyncTable() which executes a SQL +that uses the function maskingUtils.newUUID(). PostgreSQL needs a module called "uuid-ossp" to generate this UUID. + +*For example: A user synchronizes all contacts with the LASTNAME "mustermann"* + +=== Inserting contacts +If a user creates a new contact with the LASTNAME "mustermann" the contact will be automatically inserted by the process. + +=== Updating contacts +If a user updaes a contact with the LASTNAME "mustermann" the audit process will update the +column UPDATECONTACT for the entries in the table AB_SYNCCONTACT too. + +In the process_audit process a function called AuditUpdateSyncEntries() is responsible for it. +This function contains the variable "affectedDB" in which you can +define when the process_audit changes entries in the AB_SYNCCONTACT. +[NOTE] +*Standard configuration:* + "CONTACT": ["DEPARTMENT", "CONTACTROLE", "CONTACTPOSITION"], + "ORGANISATION": ["NAME"], + "ADDRESS": ["ZIP", "ADDRESS", "BUILDINGNO", "COUNTRY", "CITY", "PROVINCE", "ADDR_TYPE"], + "PERSON": ["FIRSTNAME", "LASTNAME"], + "COMMUNICATION": ["ADDR", "MEDIUM_ID", "ISSTANDARD"] + --- +If the column DEPARTMENT in CONTACT will be changed an update will be executed. +If the column STATUS in CONTACT will be changed no update will be executed. + +=== Deleting contacts +If a user deletes a contact with the LASTNAME "mustermann" the contact will be automatically deleted by the process. + +== EwsSyncToExchange_serverProcess + +*The process uses the EwsSyncContact_lib and the EwsClientSync_lib* + +=== Purpose of this Process +This process is meant to sync ADITO contacts and organisations with the configured Exchange of the Project. +Synced things are Informations that belong to a Person/Organisation +For example: +- Firstname +- Lastname +- Address +- Communication like phone / mobil / email / business email / Homepage/ fax etc. +- Organisation Name + +In the basic variant of the Contact sync we only sync to Exchange there's no writing data back to ADITO. +So if a dataset gets a change in exchange - for example changing the phonenumber - this change would not be written back to ADITO. +When then a change appears to that specific dataset in ADITO the Contact will be synced again and will overwrite the changes made in exchange. + +The EWS API also provides methods for the case when Changes in exchange should get synced to ADITO. +But at the conception phase of this process the Responsibles decided to not implement it. +There are yet a few project with containing this possibility. Please Contact your ADITO Projectmanager. + +=== Requirements +In order for syncing Contacts to Exchange there are some requirements needed. +First of all there has to be an exchange Alias with a correct configuration. + +[NOTE] +The Ews-Client Plugin needs an Impersonationuser! Ensure that it is correct set. +With the AuthMethod OAuth2 there is no Possibillity to set the Imperso User yet. +In order to configure the Impersouser anyway, change the AuthMethod to default. +Now you can edit the details for the Impersonation User. After your changes simply change +the AuthMethod to OAuth2 back. + +The process currently uses the Exchange alias "Exchange_devIntern". +Here the configured Exchange must be specified in the process, which is also +used for the user to synchronize. + +A maximum synchronization limit must be specified in the PREFERENCES_PROJECT. In the custom preferences there must be an entry "ews.syncsize". If this is not specified, 7200 is used by default. This parameter prevents too many contacts per filter from reaching outlook. + +The basic version of this process don't needs a specific folder to sync the Contacts in. +Per default the process addresses the default contact folder. +In order to distinguish the contacts from the contacts created in outlook, +a category "Adito_CRM" is specified for the contact. + +If the processes are configured in the manager, a user must be specified in addition to the "Timer type = TIMERTYPE_SERVER", so that the function which evaluates the synchronization filters in the background (db.toFilterCondition) works! +In the Dreso project, very good experiences were made with the following intervals +-> EWS - Manage Synctable: 45 min. +-> EWS - Sync to Exchange: 30 min. + +=== Debugging +In generally the Process will return Information in it's process History if something wents wrong. + +You can see it with the ADITO manger in the Process History Area or +you check the database table EWS_INFO_LOG. Every activity of the process is logged in this table. + +For manual extended debugging the Process you can just activate the Debug variable at the begin of the process. +After activating it, you'll see logs for each user and the processed data. + + +=== Process +The following will describe the functions and the functionality of the process + +==== EWSdeleteContactsForUser +Removes those Contacts in Exchange for the current user in the Process which has set an DATE_DEL Date. +The Entry gets also deleted out of the synccontact Table. + +When the debug parameter was enabled you'll also get more information which contact was successfully deleted and which not. + +==== EWSupdateContactsForUser +In that Function all that Contacts which had been recently updated getting synchronized. + +If a change in contact dataset appears, the process_audit will notice it and call +a function for updating the DATE_EDIT column and the UPDATECONTACT column to 1 in the AB_SYNCCONTACT table. + +The process will handle those, where the UPDATECONTACT column is set to 1. + +==== EWSinsertContactsForUser +This function will synchronize all new Contacts marked for sync for the current User in the batch. +By default a limit of max. 7200 contacts which can be synchronized per filter is possible +so that the performance of the process is not overloaded and the outlook profile is not flooded with contacts. + +After the first run the unique ID gets returned by exchange, we update the matching entry in the ab_synccontact table. +In order to identify each contact later again. The ID usually also contains the encoded folder destination. +BE CAREFUL: The Exchange id is case sensitive. That means Bx234967Elbn != BX234967ELBN. + + +== Important note +Sometimes it can happen that if too many contacts are created in a short time in outlook +for a user, exchange rejects the query. therefore we always send small blocks of 200. +If the exchange rejects the query we get the error +*The server cannot service this request right now. Try again later* +This is not fatal. The next time we send the package again until all contacts are in outlook. + +*BUT: We always send 200 packets of contacts to outlook and get the EXCHANGEID of the contacts as return. +If the server is restarted and we are waiting for the return from outlook, +it can happen that contacts are created twice in outlook, because we have not yet recorded the EXCHANGEID in ADITO. +The process should therefore be switched off before a planned restart* + +== Deprecated functions of the old EWS Sync + +===ewsSyncContacts_serverProcess +The whole process is outdated. +New process for this: *EwsSyncContact_serverProcess* + +===EwsClientSync_lib +The whole library provides the functions for the EWS favorites logic and is therefore outdated. +New library for this: *EwsSyncContact_lib* + +These processes will still be included in the release of the EWS, but will be dropped at some point later on. \ No newline at end of file diff --git a/process/EwsSyncToExchange_serverProcess/process.js b/process/EwsSyncToExchange_serverProcess/process.js new file mode 100644 index 0000000000000000000000000000000000000000..9c75ce818f689f9d3d374378da75cd6e13eb7b04 --- /dev/null +++ b/process/EwsSyncToExchange_serverProcess/process.js @@ -0,0 +1,55 @@ +import("system.logging"); +import("system.project"); +import("system.tools"); +import("EwsSyncContact_lib"); + +var exAlias = project.getInstanceConfigValue("calendarAlias", "Exchange").trim(); +var userArr = []; +var doDebug = false; +var userObjects = EwsClientSyncUtils.getAllExchangeUser().map(function(userName) +{ + let user = tools.getUserByAttribute(tools.NAME, [userName.trim()]); + + if(user == null) + userArr.push(userName); + + return user; +}).filter(Boolean); + +for each(let userObject in userObjects) +{ + let userID = userObject[tools.NAME]; + let userLogin = userObject[tools.TITLE]; + + try + { + let mailBox = userObject[tools.PARAMS][tools.CALENDARID]; + + if (mailBox) + { + mailBox = mailBox.trim(); + EwsClientSyncUtils.deleteExchangeContactsForUser(userID, mailBox, exAlias, userLogin, doDebug); + + EwsClientSyncUtils.updateExchangeContactsForUser(userID, mailBox, exAlias, userLogin, doDebug); + + EwsClientSyncUtils.insertExchangeContactsForUser(userID, mailBox, exAlias, userLogin, doDebug); + } + else + { + EwsClientSyncUtils.createLogEntry(userLogin, "EwsSyncToExchange", "No Exchange-Configuration found for User", "MEDIUM"); + } + } + catch(ex) + { + EwsClientSyncUtils.createLogEntry(userLogin, "EwsSyncToExchange", + logging.toLogString(ex.rhinoException != undefined ? ex.rhinoException : ex, true).substring(0, 5000), "HIGH"); + } +} + +if(userArr.length > 0) +{ + var msg = "Users where USERID is not Valid: '" + userArr.join("', '") + "'"; + EwsClientSyncUtils.createLogEntry("", "EwsSyncToExchange", msg.substring(0, 5000), "MEDIUM"); +} + +EwsClientSyncUtils.createLogEntry("", "EwsSyncToExchange", "Finished", "LOW"); \ No newline at end of file diff --git a/process/Loghistory_lib/process.js b/process/Loghistory_lib/process.js index 278b0a77affff6f75c76c52e91f71b4246c1c9f6..03c42abab2aedf2bf54e2a89bc904e35ededeaab 100644 --- a/process/Loghistory_lib/process.js +++ b/process/Loghistory_lib/process.js @@ -476,4 +476,100 @@ Translate4LogParams.generateParams = function (pRowId, pValue, pAction, pLocale) Translate4LogParams.load = function() { return new Translate4LogParams(); -}; \ No newline at end of file +}; + +/* + * + * @param {String} pTable req TableName + * @param {String} pLogin req UserName + * @param {String []} pColumns req ColumnNames + * @param {String []} pNewVals req new Values + * @param {String []} pOldVals req old Values + * @param {Date} pTimestamp req Timestamp + * @param {String} pSqlAction req SQLAction + * @param {String} pSetID req IdValue + * + * @class + */ +function AuditUpdateSyncEntries(pTable, pLogin, pColumns, pNewVals, pOldVals, pTimestamp, pSqlAction, pSetID) +{ + this.oldValues = pOldVals || []; + this.newValues = pNewVals || []; + this.table = pTable.toUpperCase(); + this.user = pLogin; + this.timestamp = pTimestamp; + this.sqlAction = pSqlAction; + this.idValue = pSetID; + this.columns = pColumns.map(function (v) + { + return v.toUpperCase(); + }); + + /** + * Here you can define for which columns the corresponding entries + * in the AB_SYNCCONTACT are marked for updating if a + * change is made to the contact/company. + */ + this.affectedDB = + { + "CONTACT": ["DEPARTMENT", "CONTACTROLE", "CONTACTPOSITION", "ADDRESS_ID"], //ADDRESS_ID if standard address changes + "ORGANISATION": ["NAME"], + "ADDRESS": ["ZIP", "ADDRESS", "BUILDINGNO", "COUNTRY", "CITY", "PROVINCE", "ADDR_TYPE"], + "PERSON": ["FIRSTNAME", "LASTNAME"], + "COMMUNICATION": ["ADDR", "MEDIUM_ID", "ISSTANDARD"] //ISSTANDARD if standard communication changes + } +} + +/** + * Gets data from Audit and process it for the history + * + * @return void + */ +AuditUpdateSyncEntries.prototype.execute = function() +{ + var that = this; + if ( !this.affectedDB[this.table] ) return; + + if ( !this.columns.some(function (elem) + { + return that.affectedDB[that.table].includes(elem); + })) return; + + var subSQL = ""; + var check = true; + + switch (this.sqlAction + "-" + this.table) + { + case "U-CONTACT": + subSQL = this.idValue; + break; + case "U-PERSON": + subSQL = newSelect("CONTACT.CONTACTID").from("CONTACT").where("CONTACT.PERSON_ID", this.idValue); + break; + case "U-ORGANISATION": + subSQL = newSelect("CONTACT.CONTACTID").from("CONTACT").where("CONTACT.ORGANISATION_ID", this.idValue); + break; + case "I-ADDRESS": + case "U-ADDRESS": + subSQL = newSelect("CONTACT.CONTACTID").from("CONTACT").where("CONTACT.ADDRESS_ID", this.idValue); + check = subSQL.arrayColumn().length > 0; + break; + case "D-ADDRESS": + subSQL = this.oldValues[this.columns.indexOf("CONTACT_ID")]; + break; + case "I-COMMUNICATION": + case "U-COMMUNICATION": + subSQL = newSelect("COMMUNICATION.OBJECT_ROWID").from("COMMUNICATION").where("COMMUNICATION.COMMUNICATIONID", this.idValue); + check = subSQL.arrayColumn().length > 0; + break; + case "D-COMMUNICATION": + subSQL = this.oldValues[this.columns.indexOf("CONTACT_ID")]; + break; + } + + if(check) + { + newWhere("AB_SYNCCONTACT.CONTACT_ID", subSQL, SqlBuilder.IN()) + .updateData(true, "AB_SYNCCONTACT", ["DATE_EDIT", "UPDATECONTACT"] , null, [vars.getString("$sys.date"), '1'], datetime.ONE_MINUTE * 5); + } +} diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js index 542b4a9acb9900a4979fc7cbbb09c6a9cd75c68c..39f55bb0383f83739af5f1e0db179ffe6d4b47e5 100644 --- a/process/Sql_lib/process.js +++ b/process/Sql_lib/process.js @@ -3889,6 +3889,84 @@ SqlMaskingUtils.prototype.concatWithSeparator = function (pFields, pSeparator, p } } +/** + * get the current timestamp + * + * @return {String} sql expression for the current timestamp + */ +SqlMaskingUtils.prototype.currentTimestamp = function() +{ + let now; + switch(this.dbType) + { + case db.DBTYPE_MARIADB10: + now = "NOW()" + break; + case db.DBTYPE_MYSQL4: + now = "CURRENT_TIMESTAMP()"; + break; + case db.DBTYPE_ORACLE10_CLUSTER: + case db.DBTYPE_ORACLE10_THIN: + case db.DBTYPE_ORACLE10_OCI: + now = "SYSTIMESTAMP"; + break; + case db.DBTYPE_POSTGRESQL8: + now = "LOCALTIMESTAMP"; + break; + case db.DBTYPE_SQLSERVER2000: + now = "GETDATE()"; + break; + case db.DBTYPE_DERBY10: + now = "CURRENT_TIMESTAMP"; + break; + default: + throw new Error(translate.withArguments("${SQL_LIB_UNSUPPORTED_DBTYPE} function: %0", ["SqlMaskingUtils.prototype.currentTimestamp"])); + + } + return now; +} + + +/** + * masks the function which will generate a new UUID + * <br> + * <p> + * Note: + * The function is not supported for the DB-Types Derby and PostgreSQL <br> + * When using a postreSQL DB ensure that the module 'uuid-ossp' is implemented otherwise it's not supported + * </p> + * + * @return {String} sql expression that creates a new UUID + */ +SqlMaskingUtils.prototype.newUUID = function() +{ + let uuID; + switch(this.dbType) + { + case db.DBTYPE_MYSQL4: + case db.DBTYPE_MARIADB10: + uuID = "UUID()"; + break; + case db.DBTYPE_ORACLE10_CLUSTER: + case db.DBTYPE_ORACLE10_THIN: + case db.DBTYPE_ORACLE10_OCI: + uuID = "(select regexp_replace(rawtohex(sys_guid()), '([A-F0-9]{8})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{12})', '\1-\2-\3-\4-\5') as UUID from dual)"; + break; + case db.DBTYPE_POSTGRESQL8: + uuID = "uuid_generate_v4()";//be carefull: to run this fuction the PostgreSQL module "uuid-ossp" has to be implemented + case db.DBTYPE_SQLSERVER2000: + uuID = "NEWID()"; + break; + case db.DBTYPE_DERBY10: + logging.log(translate.withArguments("${SQL_LIB_UNSUPPORTED_DBTYPE} function: %0", ["SqlMaskingUtils.prototype.uUID"]), logging.ERROR); + break; + default: + throw new Error(translate.withArguments("${SQL_LIB_UNSUPPORTED_DBTYPE} function: %0", ["SqlMaskingUtils.prototype.uUID"])); + + } + return uuID; +} + /** * masks the function concat * if a sql field is empty no separator will be added diff --git a/process/ewsSyncContacts_serverProcess/ewsSyncContacts_serverProcess.aod b/process/ewsSyncContacts_serverProcess/ewsSyncContacts_serverProcess.aod index fbbe02fc2fff34c845acc1f03e22f34836da4ab6..d2fb5a0d1993161f90fcefde090d71a69dcbb8e3 100644 --- a/process/ewsSyncContacts_serverProcess/ewsSyncContacts_serverProcess.aod +++ b/process/ewsSyncContacts_serverProcess/ewsSyncContacts_serverProcess.aod @@ -2,11 +2,11 @@ <process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.2" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.2.2"> <name>ewsSyncContacts_serverProcess</name> <title>Sync Exchange Contacts</title> + <description>old EWS</description> <majorModelMode>DISTRIBUTED</majorModelMode> <process>%aditoprj%/process/ewsSyncContacts_serverProcess/process.js</process> <alias>Data_alias</alias> <variants> - <element>EXECUTABLE</element> <element>LIBRARY</element> </variants> </process> diff --git a/process/process_audit/process.js b/process/process_audit/process.js index 63c0fc167cd0e0ccbdc1310c6c0469217976efca..234137317a0ec9c4d0b543e8be72f9117ca2b3bd 100644 --- a/process/process_audit/process.js +++ b/process/process_audit/process.js @@ -1,8 +1,8 @@ +import("system.logging"); +import("District_lib"); +import("Loghistory_lib"); import("system.vars"); import("system.process"); -import("EwsClientSync_lib"); -import("Loghistory_lib"); -import("District_lib"); var tableName = vars.get("$local.table"); var id = vars.get("$local.idvalue"); @@ -15,10 +15,32 @@ var userLogin = vars.get("$local.user"); if (sqlAction != 'X') { - (new LogHistoryExecutor(tableName, userLogin, columns, newvalues, oldvalues, timestamp, sqlAction, id)).execute(); - EwsClientSyncUtils.setContactToSync(tableName, id, timestamp); + try + { + (new LogHistoryExecutor(tableName, userLogin, columns, newvalues, oldvalues, timestamp, sqlAction, id)).execute(); + } + catch(err) + { + logging.log("Error while writing log entry:" + err); + } } if(sqlAction == 'I' && tableName == 'DISTRICTCONTACT'){ - DistrictUtils.notificateNewDistrictContact(id); -} \ No newline at end of file + try + { + DistrictUtils.notificateNewDistrictContact(id); + } + catch(err) + { + logging.log("Error while district notification:" + err); + } +} + +try +{ + (new AuditUpdateSyncEntries(tableName, userLogin, columns, newvalues, oldvalues, timestamp, sqlAction, id)).execute(); +} +catch(err) +{ + logging.log("Error while update Sync-Entries:" + err); +}