Summary:

An issue may occur where problems with translations may prevent the Exchange integration from synchronising tasks and appointments. The problem translations may be missing from the install, or may have been corrupted by a attempts to edit them. This issue has only ever been reported in Sage CRM 7.1, though other versiosn would likely be affected.


Symptoms:

Most typically, this issue will be noticed when tasks or appoitnmetns do not synch. Checking the scrm.xml log shows errors in the following format:

Due to processing errors UUID = 44fb8d71-d1ba-4f78-addf-5803553d0fd8 will be removed from SyncSource response feed.

java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(Unknown Source)
at com.sage.scrm.model.sync.businessrules.exchange.ExchangeSyncSourceSpecificRulesSupport.fillCrmDetailSection(ExchangeSyncSourceSpecificRulesSupport.java:326)
at com.sage.scrm.model.sync.businessrules.exchange.ExchangeSyncSourceSpecificRulesSupport.setTaskAppoOccuBodyElement(ExchangeSyncSourceSpecificRulesSupport.java:183)
at com.sage.scrm.model.sync.businessrules.exchange.AppointmentSyncSourceSpecificRules.applyBusinessRulesAppoAndOccu(AppointmentSyncSourceSpecificRules.java:91)
at com.sage.scrm.model.sync.businessrules.exchange.AppointmentSyncSourceSpecificRules.applyBusinessRules(AppointmentSyncSourceSpecificRules.java:62)
at com.sage.scrm.model.sync.SyncSourceManagerExchange.applyBusinessRules(SyncSourceManagerExchange.java:186)
at com.sage.scrm.model.sync.SyncSourceManager.createPayloadForEntity(SyncSourceManager.java:1636)
at com.sage.scrm.model.sync.SyncSourceManager.generatePayload(SyncSourceManager.java:392)
at com.sage.scrm.model.sync.SyncSourceManager$$FastClassByCGLIB$$91c4d5b7.invoke( )
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:617)
at com.sage.scrm.model.sync.SyncSourceManagerExchange$$EnhancerByCGLIB$$6aaff47d.generatePayload( )
at com.sage.scrm.model.store.SyncSourceSDataStore.handleSubsequentRequest(SyncSourceSDataStore.java:577)
at com.sage.scrm.model.store.SyncSourceSDataStore.generateContent(SyncSourceSDataStore.java:336)
at com.sage.scrm.model.store.SyncSourceSDataStore.getData(SyncSourceSDataStore.java:240)
at com.sage.scrm.controller.AbstractSyncController.getModelAndView(AbstractSyncController.java:275)
at com.sage.scrm.controller.AbstractSyncController.requestAction(AbstractSyncController.java:217)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.servlet.mvc.multiaction.MultiActionController.invokeNamedMethod(MultiActionController.java:471)
at org.springframework.web.servlet.mvc.multiaction.MultiActionController.handleRequestInternal(MultiActionController.java:408)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.sage.scrm.controller.util.SessionRequestFilter.doFilter(SessionRequestFilter.java:122)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.sage.scrm.scrmcommons.controller.util.EncodingRequestFilter.doFilter(EncodingRequestFilter.java:87)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Unknown Source)

Note:

The error is logged to the logs for the CRMJ webapp, since it is handling data access on the CRM side. All CRM logs should be included when investigating Exchange integration issues.

Cause:

Sage CRM uses translations in custom_captions to format the task and appointment bodies for Exchange. The idea is that a task or appoinment that was generated in CRM will contain the linked CRM information, such as a linked  company or Person record in the task body. The task or appointment will have a body in the following format:

Company:
  Name: 3G Homes
Account
  Name: 3G Homes Account 
Person:
  Name: Clemence Stickings
  Phone: (353) 01 6420800
Address:
  Street: 123 Fake St
  City: Funkytown

Should either of the translations responsible for this formatting be missing, or contain invalid XML, then a string index out of bounds exception will be thrown.

Resolution:

Resolving the issue in a standard release should just be a matter of replacing the entries for the following captions. Default English captions are available below:

Caption family: OutlookServerSide
Caption code: OTL_AppointmentDetails

<Company>Company:
  Name: <comp_name/>
</Company><Account>Account
  Name: <acc_name/>
</Account><Person>Person:
  Name: <pers_firstname/> <pers_lastname/>
  Phone: (<pers_phonecountrycode/>)<pers_phoneareacode/> <pers_phonenumber/>
</Person><Address>Address:
  Street: <addr_address1/>
  City: <addr_city/>
</Address>

Caption family: OutlookServerSide
Caption code: OTL_TaskDetails

<Company>Company:
  Name: <comp_name/>
</Company><Account>Account
  Name: <acc_name/>
</Account><Person>Person:
  Name: <pers_firstname/> <pers_lastname/>
  Phone: (<pers_phonecountrycode/>)<pers_phoneareacode/> <pers_phonenumber/>
</Person><Address>Address:
  Street: <addr_address1/>
  City: <addr_city/>
</Address>

 

The issue has also been reported by customers who have added a custom language, without using a language pack. As such, they may find that some translations are missing. In this instance, resolving the issue is straightforward; the captions just need to be added with the appropriate translations. An example for users using Dutch is given below:

Caption family: OutlookServerSide
Caption code: OTL_AppointmentDetails

<Company>Bedrijf:
  Naam: <comp_name/>
</Company><Account>Rekening
  Naam: <acc_name/>
</Account><Person>Persoon:
  Naam: <pers_firstname/> <pers_lastname/>
  Telefoon: (<pers_phonecountrycode/>)<pers_phoneareacode/> <pers_phonenumber/>
</Person><Address>Adres:
  Straat: <addr_address1/>
  Plaats: <addr_city/>
</Address>

Caption family: OutlookServerSide
Caption code: OTL_TaskDetails

<Company>Bedrijf:
  Naam: <comp_name/>
</Company><Account>Rekening
  Naam: <acc_name/>
</Account><Person>Persoon:
  Naam: <pers_firstname/> <pers_lastname/>
  Telefoon: (<pers_phonecountrycode/>)<pers_phoneareacode/> <pers_phonenumber/>
</Person><Address>Address:
  Straat: <addr_address1/>
  Plaats: <addr_city/>
</Address>


Status:

Carrying out the above steps should resolve the issue in all instances.