Skip to main content
Skip table of contents

Incoming web services

Basics

This article deals with the option for external systems to communicate with CURSOR-CRM (also with EVI and TINA) via web service.

Establishing the connection

WSDL

The system offers three WSDLs.

WSDL for the initiation and continuation of BPM processes

Sample: httsp://<SERVER>:X8443/<VERSION>-ejb/ProcessWebService?wsdl

Example: https://localhost:18443/soap/ProcessWebService?wsdl

You can find examples for the XML syntax for the messages to be sent to CRM in the BPM documentation (section Web Service).

WSDL for other functions

Sample: https://<SERVER>:X8443/soap/CrmWebService?wsdl

Example: https://localhost:18443/soap/CrmWebService?wsdl

Login

Every web service invocation needs its own login (HTTP basic access), which means that the data rights for CURSOR-CRM/EVI may vary.

For this purpose, user token and password (plain text) must be transferred.

In effect, only an existing CRM user can log on. We recommend creating an own user for the process.

Technology

Web services are provided via SessionBeans. A SessionBean is declared via the EJB specification as a service endpoint. The public methods of the SessionBean are approved for use in the web service in accordance with the EJB 3.1 specification.

Configuration in CURSOR-CRM/EVI

The SessionBeans WebServiceControllerBean (old version) and CrmWebServiceBean (new version) were created in order to centralize web service provision. All web services are provided via these classes. The WSDL definition is generated via the JBoss application server and provided at URL https://<SERVER>:X8443/soap/WebServiceController?wsdl or https://<SERVER>:X8443/soap/CrmWebService?wsdl.

Every web service invocation needs its own login (HTTP basic access), which means that the data rights for CURSOR-CRM/EVI may vary. The user token (all caps) and password (as HashValue) from the database must be provided.

Listing: WebServiceController.wsdl for the configuration of method string importEntities(String)
XML
<?xml version="1.0" encoding="UTF-8"?>
 
<definitions name="WebServiceController" targetNamespace="http://de.cursor.jevi.server.web/" xmlns:tns="http://de.cursor.jevi.server.web/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
	<types/>
	<message name="importEntities">
		<part name="xmlEntity" type="xsd:string"/>
	</message>
	<message name="importEntitiesResponse">
		<part name="result" type="xsd:string"/>
	</message>
	<portType name="WebServiceControllerService">
		<operation name="importEntities" parameterOrder="xmlEntity">
			<input message="tns: importEntities"/>
			<output message="tns:importEntitiesResponse"/>
		</operation>
	</portType>
	<binding name="WebServiceControllerServiceBinding" type="tns:WebServiceControllerService">
		<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
		<operation name="importEntities">
			<soap:operation soapAction=""/>
			<input>
				<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://de.cursor.jevi.server.web/"/>
			</input>
			<output>
				<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://de.cursor.jevi.server.web/"/>
			</output>
		</operation>
	</binding>
	<service name="WebServiceController">
		<port name="WebServiceControllerServicePort" binding="tns:WebServiceControllerServiceBinding">
			<soap:address location="REPLACE_WITH_ACTUAL_URL"/>
		</port>
	</service>
</definitions>

Web service call logging

Incoming and outgoing data to and from the web services provided can be exported in JBoss via the log file WebServices.log.

The log level must be set to INFO (or DEBUG) for "de.cursor.jevi.server.web.webservice".

cursor-standalone.xml
XML
<logger category="de.cursor.jevi.server.web.webservice" use-parent-handlers="false">
  <level name="INFO"/>
  <handlers>
    <handler name="WEBSERVICE"/>
  </handlers>
</logger>

This can also be done via the CLI interface:

Console
CODE
> bin/jboss-logging.bat webservice true

All input and output can be checked after activation.

Invocation - input
CODE
2014-11-20 08:16:24,581 INFO  [de.cursor.jevi.common.web.webservice.interceptor.WebServiceInLogggingInterceptor] ============= SOAP Message ==============
2014-11-20 08:16:24,581 INFO  [de.cursor.jevi.common.web.webservice.interceptor.WebServiceInLogggingInterceptor] Inbound Message
----------------------------
ID: 1
Address: https://SERVER:18443/soap/ProcessWebService
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml;charset=UTF-8
Headers: {accept-encoding=[gzip,deflate], Authorization=[Basic ABCDEFG=], connection=[Keep-Alive], Content-Length=[2497], content-type=[text/xml;charset=UTF-8], host=[SERVER:18443], SOAPAction=["startProcess"], user-agent=[Apache-HttpClient/4.1.1 (java 1.5)]}
Payload: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://web.process.cursor.de/" xmlns:var="http://variable.process.common.jevi.cursor.de/">
   <soapenv:Header/>
   <soapenv:Body>
...
</soapenv:Envelope>
--------------------------------------
Return - output
CODE
2014-11-20 08:24:06,679 INFO  [de.cursor.jevi.common.web.webservice.interceptor.WebServiceOutLoggingInterceptor] ============= SOAP Response ==============
2014-11-20 08:24:06,679 INFO  [de.cursor.jevi.common.web.webservice.interceptor.WebServiceOutLoggingInterceptor] Outbound Message
----------------------------
ID: 1
Encoding: UTF-8
Content-Type: multipart/related; type="application/xop+xml"; boundary="uuid:ae412396-af94-4ffc-95f1-31154c29a097"; start="<root.message@cxf.apache.org>"; start-info="text/xml"
Headers: {}
Payload: --uuid:ae412396-af94-4ffc-95f1-31154c29a097
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <root.message@cxf.apache.org>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns3:startProcessResponse xmlns:ns3="http://web.process.cursor.de/" xmlns:ns2="http://variable.process.common.jevi.cursor.de/">
<ns2:processWebResult>
...
</soap:Body></soap:Envelope>
--uuid:ae412396-af94-4ffc-95f1-31154c29a097--
--------------------------------------

Web services in CURSOR-CRM/EVI

WebServiceController

Method name

search

Input parameter

xmlSearch of type string (XML search import)

Output Parameter

String (XML import plugin)

WSDL

WebServiceController?wsdl

Description

A search must be forwarded to the web service as a complete XML description for execution. Each input and output field must be defined. Each field ('condition') contains a function for limiting the parameters, whereby the data type must be stated correctly. Encoding and DocType can be skipped.

Listing: Business partner search with limitation of the short name begins with CURSORListing: Business partner search with limitation of the short name begins with CURSOR
XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE CreateComplexSearch PUBLIC "ComplexSearchCreator.dtd" "ComplexSearchCreator.dtd">
<CreateComplexSearch>
	<ExtendedSearch PK="" PlainKey="" Description="" QuickSearch="false" IgnoreCase="true">
		<Query>
			<SubQuery operator="de.cursor.jevi.common.search.Operator$AndOperator" relationName="" entityName="Customer" subQueryInSearchResult="true" useExists="false" useOuterJoin="false" optionalQuery="false" breakQuery="false" hint="">
				<Condition searchResultField="true" listKey="false" defaultSearchValue="false">
					<AttributeName>MatchCode.Customer</AttributeName>
					<Function functionClassName="de.cursor.jevi.common.search.function.LikeFunction" numberOfParameters="1">
						<Parameter parameterClassName="java.lang.String" parameterValue="CURSOR" />
					</Function>
				</Condition>
				<Condition searchResultField="true" listKey="false" defaultSearchValue="false">
					<AttributeName>CustomerNo1.Customer</AttributeName>
					<Function functionClassName="de.cursor.jevi.common.search.function.NoConditionFunction" numberOfParameters="0">
						<FunctionProperty functionPropertyName="TableName" functionPropertyDataType="java.lang.String" functionPropertyValue="" />
					</Function>
				</Condition>
				<Condition ...>
				...
				</Condition>
			</SubQuery>
		</Query>
	</ExtendedSearch>
</CreateComplexSearch>

As you will hardly be able to generate this XML structure manually, it will be very helpful to first create the search in CURSOR-CRM/EVI and to then export it to XML (see illustration below). So that parameters can be added to the search later, they should be marked in the search with visible default values that can be replaced with text later in the XML (e.g. replace CURSOR with ADAC).

Figure: Exporting the business partner search to XML

The search returns all AttributeContainers as an XML result. The same structure as for the CURSOR-CRM/EVI XML export plugin is used and can therefore be exported again. Should the results contain the primary key, then it will be marked as identifyingField=true.

Listing: Result of the business partner search, suitable for XML export.
XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<Entries>
	<Entry entity="Customer" createIfNotFound="false">
		<Field name="Pk.Customer" identifyingField="true" value="ged-personpk1#customer1" />
		<Field name="Name1.Customer" value="CURSOR Software AG" />
		<Field name="CustTypeKey.Customer" value="?" />
		<Field name="PersontypeKey.Customer" value="U" />
		<Field name="CustomerNo1.Customer" value="1" />
		<Field name="MatchCode.Customer" value="CURSOR GIESSEN" />
	</Entry>
	<Entry entity="Customer" createIfNotFound="false">
		<Field name="Pk.Customer" identifyingField="true" value="ged-personpk1#customer2" />
		<Field name="MatchCode.Customer" value="CURSOR ENTWICKLUNG" />
		<Field name="Name1.Customer" value="CURSOR Software AG" />
		<Field name="CustTypeKey.Customer" value="?" />
		<Field name="PersontypeKey.Customer" value="U" />
		<Field name="CustomerNo1.Customer" value="1" />
	</Entry>
</Entries>

searchXML

Method name

searchXML

Input parameter

xmlSearch of type string (XML search import)

Output Parameter

String (XML structure, which can always be used for second generation XML import)

WSDL

WebServiceController?wsdl

Description

This web service is a continuation of the previous "search" web services.

The XML definition of a search is forwarded to the service "SearchXML" (example: see above) and the result returned is an XML structure, which can be forwarded to the second generation XML import interface (importXML, see below).

searchXMLWithParams

Method name

searchXMLWithParams

Input parameter

Search name, input parameter

Output Parameter

String (XML structure, which can always be used for second generation XML import)

WSDL

WebServiceController?wsdl

Description

A search name, followed by any number of input parameters, is forwarded for "earchXMLWithParameters". All parameter templates within the stated search are replaced in sequence (from the top down) by the forwarded parameters. A structure for the XML import is returned.

The search methods searchXML and searchXMLWithParams always deliver the XML import structure in a default configuration. All entries have the options CREATE / NO_SEARCH enabled. The relevant datasets will therefore be created again if this exact structure is sent to the import.

The structure should only be used as a basic framework and must be adapted for other operations in accordance with the documentation of the XML import interface. Specifically the attributes action and found must be adapted. When searching for a dataset (e.g. during an update or an assignment), some of the Field entries must be specified as identifyingField.

XML import v.1.0

CURSOR Software AG recommends using the methods searchXML and importXML.

Method name

importXML

Input parameter

xmlEntries of type string

Output Parameter

String (log output)

WSDL

WebServiceController?wsdl

Description

All information on the XML structure and the options for XML import can be found in the chapter XML import interface of the second generation.

Listing: Creating a new activity with contact person lookup
XML
<Entry entity="Activity" action="CREATE" found="ZERO">
	<Field name="Subject.Activity" identifyingField="true">
		<FieldValue>
			<stringValue>Bestätigung</stringValue>
		</FieldValue>
	</Field>
	<Field name="DelegatedBy.Activity" identifyingField="false">
		<FieldValue>
			<stringValue>BNE</stringValue>
		</FieldValue>
	</Field>
	<Field name="DelegatedTo.Activity">
		<FieldValue>
			<stringValue>BNE</stringValue>
		</FieldValue>
	</Field>
	<Field name="ActStatusKey.Activity">
		<FieldValue>
			<stringValue>O</stringValue>
		</FieldValue>
	</Field>
	<Field name="ActTypeKey.Activity">
		<FieldValue>
			<stringValue>TELEIN</stringValue>
		</FieldValue>
	</Field>
	<Field name="StartDate.Activity">
		<FieldValue>
			<dateTimeValue>2008-04-20T17:00:00</dateTimeValue>
		</FieldValue>
	</Field>
	<Field name="EndDate.Activity">
		<FieldValue>
			<dateTimeValue>2008-04-27T17:00:00</dateTimeValue>
		</FieldValue>
	</Field>
	<EntityLookupField name="DefaultContactPerson.Activity">
		<Field name="FirstName.ContactPerson" identifyingField="true">
			<FieldValue>
				<stringValue>Cornelia</stringValue>
			</FieldValue>
		</Field>
		<Field name="LastName.ContactPerson" identifyingField="true">
			<FieldValue>
				<stringValue>Altenhain</stringValue>
			</FieldValue>
		</Field>
		<Field name="CustomerKey.ContactPerson" identifyingField="true">
			<FieldValue>
				<stringValue>CURSOR GIESSEN</stringValue>
			</FieldValue>
		</Field>
	</EntityLookupField>
</Entry>

Entity import (XML import v. 0.5)

Method name

importEntities

Input parameter

xmlEntity of type string (XML import plugin)

Output Parameter

String (log output)

WSDL

WebServiceController?wsdl

Description

The import of entities supports new creations, data changes and links with dependent entities. Each entity is defined in the entry tag. Multiple entry tags can be added where several datasets are to be processed in parallel. The option createIfNotFound can be activated for each entry to control new creations. Each entity contains special fields, which must be unique or are mandatory to state. These options can be viewed in the field attributes of the individual fields. The unique fields are used internally to load a dataset and to change its data.

Some fields have a special format:

  • Checkbox
    It is a Boolean value: true or false

  • Date
    The format is set to dd.MM.yyyy HH:mm

  • Lookup fields
    These contain keys, e.g. MAILOFF for the activity type or ? ((Question mark) stands for the empty key)

Listing: An import using the example of activities and an associated contract
XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<Entries testRun="false">
	<Entry entity="Activity" createIfNotFound="true">
		<Field name="Subject.Activity" value="Präsentation" />
		<Field name="Text.Activity" value="Sehr geehrte Damen und Herren" />
		<Field name="ActtypeKey.Activity" value="ERINNERUNG" />
	</Entry>
	<Entry entity="Activity" createIfNotFound="true">
		<Field name="Subject.Activity" value="Angebot versendet" />
		<Field name="Text.Activity value="Anbei das Angebot bzgl. der Webservice-Schnittstelle" />
		<Field name="ActtypeKey.Activity" value="MAILAUS" />
	<Entry entity="Contract" createIfNotFound="false" >
		<Field name="ContNo.Contract" identifyingField="true" value="00001003" />
		<Field name="ProducttypeKey.Contract" identifyingField="true" value="TELE" />
		<Field name="ContTitle.Contract" value="XXXX" />
	</Entry>
</Entries>

Entity import and transformation (XML import v. 0.5)

Method name

importAndTransformEntities

Input parameter

  • xmlEntity of type string (any)

  • xsltPath of type string (path of the XSLT script or PropertyMapperID)

Output Parameter

String (log output)

WSDL

WebServiceController?wsdl

Description

Any XML structure can be forwarded to the method to ensure that the caller of the web service is not bound by the structure of the XML import plugin. That allows a web service invocation without the need for special adaptations in the invoking program.

An XSLT script ensures correct forwarding. This script must be created separately for each format. The target format is once again the import XML format for the importEntities method, which is invoked internally after the transformation.

The parameter xsltPath can contain the path to the required XSLT script. A server approval can also be used here. Alternatively, the XSLT can also be saved to the table PropertyMapper in the database. Then the ID of the database entry must be saved as parameter.

SQL
INSERT 
	INTO PropertyMapper 
	VALUES('WebserviceXSLT-Pk', 'WebserviceXSLT-ID', null,
		'<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" encoding="UTF-8"/> ... </xsl:stylesheet>',
		'SYSTEM', '', 1, GETDATE(), 'TECH_USER', GETDATE(), 'TECH_USER', null, null, null);

This menu item describes the inclusion of external web services within CURSOR-CRM so that these can be addressed in e.g. mask scripts.

CrmWebService

importXML

Method name

importXML

Input parameter

Object of type importXML

Output Parameter

Object of type importXMLResponse

WSDL

CrmWebService?wsdl

Description

This service is equivalent to importXML from WebserviceController?wsdl. Instead of an XML structure, it can receive an object mapping that structure.

All information on the XML structure and the options for XML import can be found in the chapter XML import interface of the second generation.

Request - importXML
GROOVY
def parameters = proxy.create("de.cursor.jevi.server.web.ImportXML")
  def entries = proxy.create("de.cursor.jevi.server.web.Entries")
  parameters.setEntries(entries)
 
    def entry = proxy.create("de.cursor.jevi.server.web.Entry")
      entry.setAction(proxy.create("de.cursor.jevi.server.web.Action").CREATE)
      entry.setFound(proxy.create("de.cursor.jevi.server.web.Found").ZERO)
      entry.setEntity("Customer")
    entries.getEntry().add(entry)      
 
      def fieldPk = proxy.create("de.cursor.jevi.server.web.Field")
        fieldPk.setName("Pk.Customer")
        fieldPk.setIdentifyingField(true)
        def fieldvaluePk = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
          fieldvaluePk.setStringValue("123")
        fieldPk.setFieldValue(fieldvaluePk)
      entry.getField().add(fieldPk)
 
      def field1 = proxy.create("de.cursor.jevi.server.web.Field")
        field1.setName("MatchCode.Customer")
        field1.setIdentifyingField(false)
        def fieldvalue1 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
          fieldvalue1.setStringValue("CUSTOMER MATCHCODE")
        field1.setFieldValue(fieldvalue1)
      entry.getField().add(field1)
 
      def field2 = proxy.create("de.cursor.jevi.server.web.Field")
        field2.setName("CustomerNo1.Customer")
        field2.setIdentifyingField(false)
        def fieldvalue2 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
          fieldvalue2.setStringValue("001")
        field2.setFieldValue(fieldvalue2)
      entry.getField().add(field2)
 
      def field3 = proxy.create("de.cursor.jevi.server.web.Field")
        field3.setName("CustomerNo2.Customer")
        field3.setIdentifyingField(false)
        def fieldvalue3 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
          fieldvalue3.setStringValue("001")
        field3.setFieldValue(fieldvalue3)
      entry.getField().add(field3)
 
      def field4 = proxy.create("de.cursor.jevi.server.web.Field")
        field4.setName("Name1.Customer")
        field4.setIdentifyingField(false)
        def fieldvalue4 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
          fieldvalue4.setStringValue("Customer")
        field4.setFieldValue(fieldvalue4)
      entry.getField().add(field4)
 
      def field5 = proxy.create("de.cursor.jevi.server.web.Field")
        field5.setName("Name2.Customer")
        field5.setIdentifyingField(false)
        def fieldvalue5 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
          fieldvalue5.setStringValue("Inc.")
        field5.setFieldValue(fieldvalue5)
      entry.getField().add(field5)
 
      def field8 = proxy.create("de.cursor.jevi.server.web.Field")
        field8.setName("Website.Customer")
        field8.setIdentifyingField(false)
        def fieldvalue8 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
          fieldvalue8.setStringValue("http://www.example.org")
        field8.setFieldValue(fieldvalue8)
      entry.getField().add(field8)
 
      def field22 = proxy.create("de.cursor.jevi.server.web.Field")
        field22.setName("CustTypeKey.Customer")
        field22.setIdentifyingField(false)
        field22.setClearUnknown(true)
        def fieldvalue22 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
          fieldvalue22.setStringValue("INTERESSENT")
        field22.setFieldValue(fieldvalue22)
      entry.getField().add(field22)
 
  def config = proxy.create("de.cursor.jevi.server.web.Config")
    config.setTransactionTime(300)
    config.setTestRun(false)
 
  entries.setConfig(config) 
 
def result = proxy.importXML(parameters)
Response - importXML
XML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns3:importXMLResponse xmlns:ns2="http://job.xml.common.jevi.cursor.de/" xmlns:ns3="http://web.server.jevi.cursor.de/" xmlns:ns4="http://de.cursor.jevi.common.globalvariables/" xmlns:ns5="http://de.cursor.jevi.common.customizing/" xmlns:ns6="http://binding.search.common.jevi.cursor.de/" xmlns:ns7="http://de.cursor.jevi.common.keys/" xmlns:ns8="http://variable.process.common.jevi.cursor.de/">
			<return success="true">
				<Config transactionTime="300" testRun="false"/>
				<Entry action="CREATE" found="ZERO" entity="Customer">
					<CompletionType>SUCCESS</CompletionType>
					<ModificationType>NO_MODIFICATION</ModificationType>
					<PrimaryKeys>
						<Pk value="123"/>
					</PrimaryKeys>
					<Field name="Pk.Customer" identifyingField="true">
						<FieldValue>
							<stringValue>123</stringValue>
						</FieldValue>
					</Field>
				</Entry>
			</return>
		</ns3:importXMLResponse>
	</soap:Body>
</soap:Envelope>

searchXML

Method name

searchXML

Input parameter

Object of type searchXML

Output Parameter

Object of type searchXMLResponse

WSDL

CrmWebService?wsdl

Description

This service is equivalent to searchXML from WebserviceController?wsdl. Instead of an XML structure, it can receive an object mapping that structure.

Request searchXML
GROOVY
def parameters = proxy.create("de.cursor.jevi.server.web.SearchXML")
 
  def search = proxy.create("de.cursor.jevi.server.web.SearchXML\$Search")
    parameters.search = search
 
    def extendedSearch = proxy.create("de.cursor.jevi.common.search.binding.ExtendedSearch")
    search.extendedSearch.add(extendedSearch)
      extendedSearch.setPK("")
      extendedSearch.setPlainKey("GeneratedDefaultSearchForActivity")
      extendedSearch.setDescription("") 
      extendedSearch.setQuickSearch(false)
      extendedSearch.setIgnoreCase(true)
 
      def query = proxy.create("de.cursor.jevi.common.search.binding.Query")
      extendedSearch.query.add(query)
   
        def subQuery = proxy.create("de.cursor.jevi.common.search.binding.SubQuery")
        query.setSubQuery(subQuery)
          subQuery.setOperator("de.cursor.jevi.common.search.Operator\$AndOperator")
          subQuery.setEntityName("Activity")
          subQuery.setSubQueryInSearchResult(true)
          subQuery.setRelationName("")
 
          def condition = proxy.create("de.cursor.jevi.common.search.binding.Condition")
          subQuery.getConditionOrSubQuery().add(condition)
            condition.setAttributeName("Subject.Activity")
            condition.setSearchResultField(true)
 
            def function = proxy.create("de.cursor.jevi.common.search.binding.Function")
            condition.setFunction(function)
              function.setFunctionClassName("de.cursor.jevi.common.search.function.LikeFunction")
              function.setNumberOfParameters(1)
 
              def functionParameter = proxy.create("de.cursor.jevi.common.search.binding.Parameter")
              function.getParameterOrParameterLookupVO().add(functionParameter)
                functionParameter.setParameterValue("v")
                functionParameter.setParameterClassName("java.lang.String")
 
def result = proxy.searchXML(parameters)
Response - searchXML
XML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns3:searchXMLResponse xmlns:ns2="http://job.xml.common.jevi.cursor.de/" xmlns:ns3="http://web.server.jevi.cursor.de/" xmlns:ns4="http://de.cursor.jevi.common.globalvariables/" xmlns:ns5="http://de.cursor.jevi.common.customizing/" xmlns:ns6="http://binding.search.common.jevi.cursor.de/" xmlns:ns7="http://de.cursor.jevi.common.keys/" xmlns:ns8="http://variable.process.common.jevi.cursor.de/">
			<return success="false">
				<Config transactionTime="300" version="1.0" testRun="false"/>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Vertragsverlaengerung</stringValue>
						</FieldValue>
					</Field>
				</Entry>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Vertragsverlaengerung</stringValue>
						</FieldValue>
					</Field>
				</Entry>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Vertragsverlaengerung angenommen</stringValue>
						</FieldValue>
					</Field>
				</Entry>
			</return>
		</ns3:searchXMLResponse>
	</soap:Body>
</soap:Envelope>

searchXMLWithParams

Method name

searchXMLWithParams

Input parameter

Object of type searchXMLWithParams

Output Parameter

Object of type searchXMLWithParamsResponse

WSDL

CrmWebService?wsdl

Description

This service is equivalent to searchXMLWithParams from WebserviceController?wsdl. Instead of an XML structure, it can receive an object mapping that structure.

Request - searchXMLWithParams
GROOVY
def parameters = proxy.create("de.cursor.jevi.server.web.SearchXMLWithParams")
  parameters.searchName = "ActivitiesWithParams"
  parameters.getParams().add("v") // Template "Subject.Activity"
  parameters.getParams().add("A") // Template "ActStatusKey.Activity
 
def result = proxy.searchXMLWithParams(parameters)
Response - searchXMLWithParams
XML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns3:searchXMLWithParamsResponse xmlns:ns2="http://job.xml.common.jevi.cursor.de/" xmlns:ns3="http://web.server.jevi.cursor.de/" xmlns:ns4="http://de.cursor.jevi.common.globalvariables/" xmlns:ns5="http://de.cursor.jevi.common.customizing/" xmlns:ns6="http://binding.search.common.jevi.cursor.de/" xmlns:ns7="http://de.cursor.jevi.common.keys/" xmlns:ns8="http://variable.process.common.jevi.cursor.de/">
			<return success="false">
				<Config transactionTime="300" version="1.0" testRun="false"/>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Vertragsverlaengerung</stringValue>
						</FieldValue>
					</Field>
					<Field name="ActStatusKey.Activity" fieldType="PK" identifyingField="false">
						<FieldValue>
							<stringValue>S_ACTSTATUS-A</stringValue>
						</FieldValue>
					</Field>
				</Entry>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Vertragsverlaengerung angenommen</stringValue>
						</FieldValue>
					</Field>
					<Field name="ActStatusKey.Activity" fieldType="PK" identifyingField="false">
						<FieldValue>
							<stringValue>S_ACTSTATUS-A</stringValue>
						</FieldValue>
					</Field>
				</Entry>
			</return>
		</ns3:searchXMLWithParamsResponse>
	</soap:Body>
</soap:Envelope>

searchXMLOrderBy

Method name

searchXMLOrderBy

Input parameter

Object of type searchXMLOrderBy

Output Parameter

Object of type searchXMLOrderByResponse

WSDL

CrmWebService?wsdl

Description

This service is an extension of searchXML from CrmWebService?wsdl. It allows the sorting of the search result.

Request - searchXMLOrderBy
GROOVY
def parameters = proxy.create("de.cursor.jevi.server.web.SearchXMLOrderBy")
 
  def search = proxy.create("de.cursor.jevi.server.web.SearchXMLOrderBy\$Search")
  parameters.search = search
 
    def extendedSearch = proxy.create("de.cursor.jevi.common.search.binding.ExtendedSearch")
    search.extendedSearch.add(extendedSearch)
      extendedSearch.setPK("")
      extendedSearch.setPlainKey("GeneratedDefaultSearchForActivity")
      extendedSearch.setDescription("") 
      extendedSearch.setQuickSearch(false)
      extendedSearch.setIgnoreCase(true)
 
      def query = proxy.create("de.cursor.jevi.common.search.binding.Query")
      extendedSearch.query.add(query)
 
        def subQuery = proxy.create("de.cursor.jevi.common.search.binding.SubQuery")
        query.setSubQuery(subQuery)
          subQuery.setOperator("de.cursor.jevi.common.search.Operator\$AndOperator")
          subQuery.setEntityName("Activity")
          subQuery.setSubQueryInSearchResult(true)
          subQuery.setRelationName("")
 
          def condition = proxy.create("de.cursor.jevi.common.search.binding.Condition")
          subQuery.getConditionOrSubQuery().add(condition)
            condition.setAttributeName("Subject.Activity")
            condition.setSearchResultField(true)
 
            def function = proxy.create("de.cursor.jevi.common.search.binding.Function")
            condition.function = function
              function.setFunctionClassName("de.cursor.jevi.common.search.function.LikeFunction")
              function.setNumberOfParameters(1)
  
              def functionParameter = proxy.create("de.cursor.jevi.common.search.binding.Parameter")
              function.getParameterOrParameterLookupVO().add(functionParameter)
                functionParameter.setParameterValue("a")
                functionParameter.setParameterClassName("java.lang.String")
 
  def searchOrder = proxy.create("de.cursor.jevi.server.web.SearchOrder")
  parameters.searchOrder = searchOrder
 
    def searchOrderEntry = proxy.create("de.cursor.jevi.server.web.SearchOrderEntry")
    searchOrder.searchOrderEntry.add(searchOrderEntry)
      searchOrderEntry.attributeName = "Subject.Activity"
      searchOrderEntry.order = proxy.create("de.cursor.jevi.server.web.OrderType").ASCENDING
      searchOrderEntry.searchSortOrder = proxy.create("de.cursor.jevi.server.web.OrderType").ASCENDING
 
def result = proxy.searchXMLOrderBy(parameters)
Response - searchXMLOrderBy
XML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns3:searchXMLOrderByResponse xmlns:ns2="http://job.xml.common.jevi.cursor.de/" xmlns:ns3="http://web.server.jevi.cursor.de/" xmlns:ns4="http://de.cursor.jevi.common.globalvariables/" xmlns:ns5="http://de.cursor.jevi.common.customizing/" xmlns:ns6="http://binding.search.common.jevi.cursor.de/" xmlns:ns7="http://de.cursor.jevi.common.keys/" xmlns:ns8="http://variable.process.common.jevi.cursor.de/">
			<return success="false">
				<Config transactionTime="300" version="1.0" testRun="false"/>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Anfrage #123 Aktivität zu Täpper bei Somentec</stringValue>
						</FieldValue>
					</Field>
				</Entry>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Anfrage #123 Aktivität zu Täpper bei Somentec</stringValue>
						</FieldValue>
					</Field>
				</Entry>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Anfrage #133 Aktivität zu Täpper bei ENTEGA</stringValue>
						</FieldValue>
					</Field>
				</Entry>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Anfrage #133 Aktivität zu Täpper bei TäPPER HANS</stringValue>
						</FieldValue>
					</Field>
				</Entry>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Angebot</stringValue>
						</FieldValue>
					</Field>
				</Entry>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Angebotsversand</stringValue>
						</FieldValue>
					</Field>
				</Entry>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Antwort von Meyer mit Link zum VL</stringValue>
						</FieldValue>
					</Field>
				</Entry>
			</return>
		</ns3:searchXMLOrderByResponse>
	</soap:Body>
</soap:Envelope>

searchXMLWithParamsOrderBy

Method name

searchXMLWithParamsOrderBy

Input parameter

Object of type searchXMLWithParamsOrderBy

Output Parameter

Object of type searchXMLWithPramsOrderByResponse

WSDL

CrmWebService?wsdl

Description

This service is an extension of searchXMLWithParams from CrmWebService?wsdl. It allows the sorting of the search result.

Request - searchXMLWithParamsOrderBy
GROOVY
def parameters = proxy.create("de.cursor.jevi.server.web.SearchXMLWithParamsOrderBy")
  parameters.searchName = "ActivitiesWithParams"
  parameters.getParams().add("v") // Template "Subject.Activity"
  parameters.getParams().add("A") // Template "ActStatusKey.Activity"
 
  def searchOrder = proxy.create("de.cursor.jevi.server.web.SearchOrder")
  parameters.searchOrder = searchOrder
 
    def searchOrderEntry = proxy.create("de.cursor.jevi.server.web.SearchOrderEntry")
    searchOrder.searchOrderEntry.add(searchOrderEntry)
      searchOrderEntry.attributeName = "Subject.Activity"
      searchOrderEntry.order = proxy.create("de.cursor.jevi.server.web.OrderType").ASCENDING
      searchOrderEntry.searchSortOrder = proxy.create("de.cursor.jevi.server.web.OrderType").ASCENDING
 
def result = proxy.searchXMLWithParamsOrderBy(parameters)
Response - searchXMLWithParamsOrderBy
XML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns3:searchXMLWithParamsOrderByResponse xmlns:ns2="http://job.xml.common.jevi.cursor.de/" xmlns:ns3="http://web.server.jevi.cursor.de/" xmlns:ns4="http://de.cursor.jevi.common.globalvariables/" xmlns:ns5="http://de.cursor.jevi.common.customizing/" xmlns:ns6="http://binding.search.common.jevi.cursor.de/" xmlns:ns7="http://de.cursor.jevi.common.keys/" xmlns:ns8="http://variable.process.common.jevi.cursor.de/">
			<return success="false">
				<Config transactionTime="300" version="1.0" testRun="false"/>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Vertragsverlaengerung</stringValue>
						</FieldValue>
					</Field>
					<Field name="ActStatusKey.Activity" fieldType="PK" identifyingField="false">
						<FieldValue>
							<stringValue>S_ACTSTATUS-A</stringValue>
						</FieldValue>
					</Field>
				</Entry>
				<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
					<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
						<FieldValue>
							<stringValue>Vertragsverlaengerung angenommen</stringValue>
						</FieldValue>
					</Field>
					<Field name="ActStatusKey.Activity" fieldType="PK" identifyingField="false">
						<FieldValue>
							<stringValue>S_ACTSTATUS-A</stringValue>
						</FieldValue>
					</Field>
				</Entry>
			</return>
		</ns3:searchXMLWithParamsOrderByResponse>
	</soap:Body>
</soap:Envelope>

REST interface for document handling

Using Web service calls, it is possible to receive documents from the CRM system and transfer them to the CRM system.

Service documentation https://carmenbig.cursor.de:18443/rest/doc/v1/services/document

Action

Method

URL

Parameter

Result

creation

POST

https://server.baseUrl/rest/api/document/v1/documents?documentName=<documentName>

documentName QUERY, document FORM-DATA

{"documentPk":"fvvvvvuov9tr21bsa6pc7qDo","name":"Doppelter-Haupt_AP.jpg","updateDate":"2017-10-13T07:12:21Z","size":163938}DocumentMetaDataDTO

read

GET

https://server.baseUrl/rest/api/document/v1/documents/<documentPk>/read

documentPk PATH

binary

edit

GET

https://server.baseUrl/rest/api/document/v1/documents/<documentPk>/edit

documentPk PATH

binary

return

POST

https://server.baseUrl/rest/api/document/v1/documents/<documentPk>/return?documentName=<documentName>

documentName QUERY, document FORM-DATA

{"documentPk":"fvvvvvuov9tr21bsa6pc7qDo","name":"Doppelter-Haupt_AP.jpg","updateDate":"2017-10-13T07:12:21Z","size":163938}DocumentMetaDataDTO

discard

GET

https://server.baseUrl/rest/api/document/v1/documents/<documentPk>/discard

dokumentPk PATH

{"documentPk":"fvvvvvuov9tr21bsa6pc7qDo","name":"Doppelter-Haupt_AP.jpg","updateDate":"2017-10-13T07:12:21Z","size":163938}DocumentMetaDataDTO

Web service for receiving time events

Time events can be stored in the CRM via Rest Service.

  • URL: /rest/api/event/v1/events

  • Documentation: /rest/doc/v1/services/event

The call as POST can be given the type of event, optionally the time (default is the time of the call) and a payload in JSON format. The eventType is a technical identifier of the time event and should be structured as follows:

<Top-Level-Domain>.<Second-Level-Domain>.<technical identifier> → de.cursor.portalAccess, org.company.calculation

CODE
{
  "eventType" : "domain.myEventType",
  "payload" : {
    "key1" : "stringValue",
    "key2" : 1987,
    "key3" : true
  }
}

An alternative service URL has been provided to simplify the call:

URL: /rest/api/event/v1/events/type/{eventType}

Example: /rest/api/event/v1/events/type/domain.myEventType

CODE
{
  "key1" : "stringValue",
  "key2" : 1987,
  "key3" : true
}

Additional parameters in the URL can be used to provide the services with further options. (Example: /rest/api/event/v1/events/type/domain.myEventType?async=true&parallel=true)

  • dateTime: The date of the event is determined from the current system time by default. This parameter can be used to overwrite the date in ISO-8601 format.

  • async: Can be activated with the value "true". The event is placed in a queue and checked. The event is processed asynchronously.

  • parallel: With asynchronous execution of events, the order between service call and execution remains stable. To speed up the processing of events, processing can be parallelized. The order of these events is then no longer certain.

Only with asynchronous processing can an order of events be controlled. With synchronous, direct processing, individual service calls are not synchronized with each other.

This call creates a time event in the clipboard. The data can be viewed by the administrator.

Each event can be checked using the C0Event.check() method. The check also takes place during asynchronous processing directly when the service is called.
The further processing logic of the events is triggered synchronously in the script library under C0Event.process().

It is important to ensure that the checking of events is implemented with high performance. If the check of an event exceeds a period of 50 ms, a message is sent to the system administrator.

The methods of the script library can be overridden and extended in the client layer.

SC0Event
GROOVY
@BpmScript @Released @Override
private Boolean check(String eventType, Map<String, Object> payloadRequest, Map<String, Object> payloadResponse)
{
  // ...

  return super.check(eventType, payloadRequest, payloadResponse);
}

@BpmScript @Released @Override
private void process(String eventPk, Date eventDate, String eventType, Map<String,Object> payloadRequest, Map<String,Object> payloadResponse)
{
  // ...
  
  super.process(eventPk, eventDate, eventType, payloadRequest, payloadResponse);
}

In the script class, you can react to the type of the time event to trigger customer-specific processing logic. The type can be freely selected by the caller or predefined in the key range "Time event type". The call contains the following parameters:

  • eventPk: The primary key for the dataset of the time event

  • eventDate: The time of the time event

  • eventType: The key to selecting the logic

  • payloadRequest: A map with the values from the payload of the Rest Service

  • payloadResponse: A map for the return of results of the logics to the caller

A predefined logic is the "CreateActivity" type. This allows the rapid new creation of activities by the service. The fields of the activity can be preassigned in the payload.

CreateActivity: Request
CODE
{
    "eventType": "CreateActivity",
    "payload": {
        "myfield1": "myValue1",
        "Activity": {
            "Subject": "Mein Betreff",
            "Text.Activity": "<html><body><p>Mein Text</p></boby></html>",
            "StartDate": "2020-02-02T20:20:20+01:00", // optional
            "EndDate": "2020-02-02T20:35:20+01:00",   // optional
            "ActStatusKey": "S_ACTTYPE-E",
            "ActTypeKey": "S_ACTSTATUS-O",
            "DelegatedBy": "ged-personpkTechUser#TechUser",
            "DelegatedTo": "ged-personpkTechUser#TechUser",
            "IsTaskRead": true,
            "ContactCosts": 1,
            "FreeNumber1": 1.23456789
        }
    }
}

The definition of the activity must be stored under the value "Activity". For the conversion from Map to IContainer the WorkSpaceScriptUtils.converToIContainer() method is used. The start and end dates are preset by default with the time of the event. The primary key of the event and activity is returned as the result.

CreateActivity: Response
CODE
{
    "id": "fvvvvvucldhsc1e11vhi8iEvAr",
    "status": "DONE",
    "payload": {
        "Activity": {
            "Pk.Activity": "1vlq1uh1e11vhideAc"
        }
    }
}

If a link between time event and activity is desired, a C2 lookup field must be excluded in the activity and the logic in the script method must be overridden

C0Event.createEntity
JAVA
entityMap.put("C2EventKey", eventPk); //Neues C2-Feld in Aktivitäten aufnehmen

super.createEntity(eventPk, eventDate, entityName, entityMap, payloadResponse)

Dynamic addressing of different URLs in web services

A web service call in the CRM system can be used dynamically in such a way that different URLs can be addressed with one web service.

For example, in order to distinguish the web service configuration between development system, QA system and production system, the WSDL definition can now be outsourced to a global variable.

It is possible to store the URL for the WSDL definition as well as the entire XML definition in XML format, in which the URL for the service is stored.

During the new creation of a web service, the global variable can now also be selected as an option to the URL or file. The availability check and service creation can then be performed as usual.

After the customizing transport of the global variable and the web service definition, in the other systems only the URL in the global variable of the service must be adjusted.


JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.