[2012] sybase mobilecsybase® mobile sales for sap® crm: crm customization and mobile application...

70
WHITE PAPER www.sybase.com Jagdish Bansiya, Chris Jobson and Lee Cheetham Sybase ® Mobile Sales for SAP ® CRM: CRM Customization and Mobile Application Enhancements

Upload: bangalore-techie

Post on 13-Feb-2017

222 views

Category:

Technology


1 download

TRANSCRIPT

white paper

www.sybase.com

Jagdish Bansiya, Chris Jobson and Lee Cheetham

Sybase® Mobile Sales for SAP® CRM: CRM Customization and Mobile Application Enhancements

taBLe OF CONteNtS 1 Introduction 1 Customization and Enhancement of the Sybase Mobile Sales for SAP CRM 2 Architecture Design of the Sybase Mobile Sales for SAP CRM 5 Mobile CRM Customizations 13 Custom Coding: Adding a New Process to Windows Mobile Sales 15 Adding a New Process 21 Update the ImageManager Class 22 Create the View UI Component 26 Plugging the New Process Into the Home Screen 29 Create the Inspect Form 35 Create the Act UI Component 40 Final UI Change 43 Custom Enhancements (CE) 65 Implementing Custom Extensions

1

iNtrOduCtiONThe Sybase Mobile Sales for SAP CRM solution includes a fully functional, out-of-the-box mobile application for

customer relationship management (CRM) sales scenarios. The Sybase Mobile Sales for SAP CRM 1.2 application on Windows Mobile implements sales functionality of business partner (accounts and contacts) management, activities, leads and opportunities, sales documents and analytics. Mobile users can view, update and create master data or transactional objects (with some differences across platforms and objects). The CRM sales mobile content is delivered with an SAP add-on, the Gateway 1.1 to SAP NetWeaver® Mobile. Customers and partners must obtain this product from the SAP Service Marketplace and install it on NetWeaver Mobile 7.1 SP09+. The standard Sybase mobile application works the standard sales content called MAS_SMART_PHONE_V001.

Most SAP CRM customers have customized the standard CRM. The Sybase Mobile Sales for SAP CRM solution supports CRM customizations that are implemented on desktop systems and that customers also want to access from the mobile CRM application. This document describes how the Sybase Mobile Sales for SAP CRM solution and application can be customized and enhanced. The terminology we will use includes:

• EntitySetDefinitionforMobileApplications(ESDMA).The Web Service Definition Language (WSDL) generated by the Gateway 1.1 to SAP NetWeaver Mobile that describes the objects, attributes, relationships and customization data for the Sybase Mobile Sales for SAP CRM application.

• StandardcontentforCRM.The standard content definition for the Sybase Mobile Sales for SAP CRM application that SAP releases (delivered as an ESDMA bundle) can be downloaded from the SAP Service Marketplace.

• Standardapplication.The mobile application that Sybase developed, certified and released. Standard applications are supported by SAP and Sybase as defined in the support agreement and are eligible for automatic upgrade handling when new versions of the application are made available.

• CRMcustomization.Business process configurations that customers do to the standard CRM systems to make the out-of-box process fit their business needs.

CuStOmizatiON aNd eNhaNCemeNt OF the SyBaSe mOBiLe SaLeS FOr Sap CrmThe Sybase Mobile Sales for SAP CRM solution supports five forms of customizations and enhancements.

1. MobileCRMcustomization requires no change to the mobile application. Examples of mobile CRM customization include changing back-end languages, actual and planned dates, activity types, select and status lists, business partner determination rules and information such as transaction codes. These changes are delivered to the Sybase mobile application through the ESDMA customization object. The mobile application uses the information in the customization object as metadata to drive its capabilities.

2.Customenhancements enable the addition of new fields and attributes to existing mobile application objects without requiring changes to the mobile application or the Sybase middleware components. Using this approach ensures supportability and compatibility with new versions of the Sybase mobile application. Changes must be made in the CRM back end using the BADI extension process, which follows standard SAP-recommended practices. (BADIs, or Business Add-Ins, are specialized add-ins to the Business Application Programming Interface [BAPI] wrappers used to push data from CRM to the Data Orchestration Engine, or DOE, and thus to the mobile device.)

3.Applicationbranding allows customers and partners to change limited aspects of the application look and feel, such as logos and images. These alterations can be made without changing source code, because the information is externalized in various resources. This category of change includes language translation. Customers can have existing resource bundles translated into different languages. Application branding requires that the application be rebuilt, depending on what the change is and how it is done. Sybase does not support and ensure upgrade compatibility if branding changes are performed outside the externalized resources.

2

4.Mobileapplicationconfigurationallows the mobile application to disable implemented mobile processes from the application. This capability is available only for top-level objects. Disabling functionality also ensures that any reference to the functionality from other objects and menus is removed. This capability uses a configuration file that is bundled with the application for Windows Mobile; it uses a Sybase server-side object for iPhone®. Disabling (hiding) fields or changing the order in which they appear is also supported and implemented differently for the two mobile applications. On Windows Mobile, the order and hiding of fields uses the template configuration files, whereas on iPhone, these types of changes are implemented using a server-side object that must be configured. Changes made in this category require that the application be relinked. Changes and the ability to upgrade are supported, although some manual merge steps may be required to handle changed UI templates.

5.Customextensions may be warranted if the customization and enhancements that the customer requires cannot be effected with any other approach. This option is for customers who want to implement new business processes that are not available in the mobile application or want to change the business logic of existing processes. Special skills and knowledge may be required because this approach requires customers or partners to work with the source code of the Sybase mobile applications. Source code changes are not supported through the standard support channels, and upgrades to new versions of Sybase applications must be manually applied.

The Sybase Mobile Sales for SAP CRM application defines a set of extensions framework, APIs and recommended practices that allow customization while keeping the core standard application mostly unchanged. Customizations in this category may require new source code files. Sybase recommends that if you customize the mobile application, follow the best practices of organizing the new code and try to not alter any of the standard source files.

arChiteCture deSigN OF the SyBaSe mOBiLe SaLeS FOr Sap Crm To understand how customization and extensions are handled and supported in the Sybase Mobile Sales for SAP

CRM application, you should understand its overall design, architecture, technologies, frameworks and components. The general approach and architecture apply to both the iPhone CRM and Windows Mobile CRM applications, although they are slightly different because of the technology stacks, platform features and restrictions. (Significant differences are pointed out as necessary.) Though these applications are different in structure, the way they interact with the Sybase Unwired Platform server is similar. The Sybase Unwired Platform server cannot tell the difference between iPhone and Windows Mobile requests and responses.

The figure below shows the architecture that is generally applicable to both iPhone and Windows Mobile CRM applications.

2

SQLLiteData Model

Application User InterfaceGlue + screen flow code

Application Business Objects (ABO)Hand Written

Consolidates access across multipleMBOs and implements CRM business logic

Generated MBOWith SQL Interface

Proj

ectB

uild

Tem

plat

e

Appl

icat

ion

Tem

plat

e

Conf

igur

atio

n Fi

les

UI F

ram

ewor

k (P

S)

Resc

o Te

mpl

ates

Reso

urce

Bun

dles

Imag

es a

nd Ic

ons

3

ApplicationComponents/LayersThe mobile applications consist of four distinct layers of functionality. Clear and visible code and packaging-level

separations exist between each of these layers. Each layer provides well-defined services through interfaces to the layer above it. A different functional team develops and delivers each layer.

1. TheSQLLitedatamodelcorresponds to objects, nodes and other management tables that the generated classes automatically define the first time the application is used during the initialization process. This activity happens on the device. More than 100 tables are created for the default CRM ESDMA that SAP ships. Any change in generated classes requires that the data model be recreated. Incremental updates of the data model on the device are not supported.

2. GenerateMobileBusinessObject(MBO)classes (C# or Objective C) on the Sybase Unwired Platform server by taking an AFX document generated from the ESDMA and running the TemplateJ engine for code generation. The generated classes represent straightforward Object Relationship Mapping (ORM) code between attributes of ESDMA objects and nodes to SQL table column definitions. The generated MBO code ensures that the attribute type information is correctly maintained and converted when you are working with database column types. The structural relationship between objects and nodes in the ESDMA WSDL is not maintained in the generated ORM. The relationship is flattened to independent tables. Separate MBO objects are generated for each object and its associated nodes in the ESDMA definition. An automated naming convention that involves the concatenation of the parent object and node name is adopted for the MBOs. Only one level of parent-child relationship from ESDMA to generated objects is handled by the transformation (ESDMA to AFX) and code generation (AFX to C#/Objective C code) process. This is important, because the general ESDMA design allows for multiple levels of node nesting.

Generated MBOs are unsuitable for direct consumption in the mobile application for these reasons:

a. MBOs do not capture the structural relationship between objects. (Application Business Objects, or ABOs, model this relationship.)

b. MBOs represent an ORM layer, which makes them difficult to be directly consumed in the application layer. There are too many MBOs (more than 100) that can be used directly without complicating the application User Interface (UI) code. The ABOs define a simplified access layer for the UI code to get access to data and operations.

c. Several MBO CRM back-end data and business rules must be captured and implemented on the device side:

i. Field validation rules – implementation for datatype validations and required fields. The information for required fields is not specified anywhere and must be injected into the application on the device side.

ii. Transaction code translation rules – information from the ESDMA Customization Object is used to translate numeric codes to human-readable text strings. Business rules and knowledge for interpreting the data of the ESDMA Customization Object is encapsulated in the ABOs.

iii. Authorization rules – validation if users are authorized to perform particular operations. The logic for this has not been implemented because the DOE has not been set up to provide authorization rules and data to the application through the customization objects.

iv. Semantic mapping layer – behavioral semantics. v. Handling of child nodes and notes.

3. Applicationbusinessobjects(ABOs)create a practical and reusable layer of abstraction, incorporating business and functional knowledge of the CRM application.

a. Defined top-level ABOs include Account, Contacts, Activities, Leads, Opportunity, Sales Order and Analytics for the mobile applications UI frameworks to use. These objects provide everything the UI frameworks need to build the application and are the only layer of data and operations that the application UI code interacts with.

4

b. The new ABOs represent reusable software components that can be used across variants of the mobile CRM application. These ABOs define a layer of supportable contracts around which rules for customization, extensibility and support are built.

4.TheapplicationUI is the top-most layer of the application, which defines and provides the user experience such as UI screens and screen flows. The application UI layer is built on top of code and functionality modules.

a. Projectbuildtemplatedefines the dependency and compilation structure for the mobile application. The build template defines all of the dependent components, libraries, resources files, bundles, graphics and images, certificates and subprojects that are necessary to compile and generate the deployable application bundles. These files define the nonfunctional shell of the application. Physically, the project build template is represented by the Visual Studio or XCode IDE project template files.

b. Applicationtemplate defines everything that is common to the entire application, such as the core structure and organization of the UI code and frameworks used in the mobile application. For example, this template defines the use of login/logout screens, idle timeouts, re-authentication, headers, footers, common function structures and menu structure. It defines all the functionality and interfaces that do not change based on any specific function or operation of the application.

c. Configurationfilesrepresent external physical files that are human-readable and editable. These files contain information that the application uses for configuration. These configuration files represent information outside of the application, so that changes can be made without requiring the application to be recompiled. The configuration files represent most of the implementation strategy for customizing the Sybase Mobile Sales for SAP CRM application.

d. UIframework is a set of services that provides commonly needed capabilities for building Windows Mobile applications. These services allow for the instantiation and management of UI objects using well-defined paradigms such as stacks and wizards. The services capture many of the best practices of Windows Mobile application development that are applicable across any mobile application.

e. Rescotemplates are rich graphics components and widgets for Windows Mobile that Resco, a third party, supplies. The Windows Mobile CRM application uses the Resco list controls, table controls and charts for its UI experience. The presentation of Resco controls is based on an external (XML) template file, which specifies the attributes, location, placement and size. Typically, different device resolutions, landscape versus portrait orientation handling and UI styles require different sets of Resco presentation templates. This externalization of presentation using the Resco control templates represents an important part of the strategy for customizing Sybase Mobile Sales for SAP CRM on Windows Mobile. iPhone application design uses a similar approach of external screen definition.

f. Resourcebundlesare all literal strings, images, icon references and locale information that the application uses. Resource bundles are externalized through language and resource bundles and are the primary units for language, locale and branding customizations.

g. Imagesandicons are graphics and pictures, including branding images such as company logos and application icons, which the mobile application uses. All images and icons are organized using a well-defined structure in the project bundle. Graphics and icons are sensitive to resolutions; therefore, multiple sets are necessary to ensure that the application looks good on different device resolutions and orientations.

5

mOBiLe Crm CuStOmizatiONSThis section details approaches for customizing the Mobile Sales application.

WindowsMobileSalesBrandingBranding allows an organization to align the Windows Mobile Sales application to suit its corporate standards. The

deployed Windows Mobile Sales application contains a main Mobile Sales installation folder, under which is located a Resources folder, which in turn contains a folder called Images. The Images folder contains all the images and icons used within the Windows Mobile CRM application. Some or all of the image files may be replaced as necessary, but the existing file names and sizes must remain consistent with the original versions of the images.

Changing any of the image files does not require the Windows Mobile Sales application to be recompiled; however, the CAB file used to deploy the Windows Mobile Sales application must be rebuilt so that it contains the new images. Third-party CAB file tools that allow individual files to be replaced within an existing CAB file are available. An alternative approach is to deploy and install Mobile Sales and then overwrite the default image files with branded images using a deployment/configuration tool such as Afaria.

The images in Windows Mobile Sales may be categorized into three groups.

• Iconimages.These provide images for the lists views as well as the Home screen buttons. Icon style images must be provided in three sizes (16x16, 32x32 and 64x64 pixels) to support the resolutions and screen sizes of Windows mobile devices.

• SplashScreenimages.Splash Screen images are shown as the Windows Mobile CRM application starts up. These images are different across the Professional and Standard platforms. The images must be supplied in landscape and portrait format to support devices that support multiple orientations. The splash screen images are prefixed with the word “Splash.” For example, Splash_240.png refers to the 240x240 pixel splash screen image.

• HomeScreenimages. Home screen images are the banner title and a line graphic that appear at the top of the Home screen. Home screen images are prefixed with the word “Home”; for example, Home_title.png.

All the image files used with the Windows Mobile Sales application are stored in the portable network graphics (PNG) format.

This example of the Windows Mobile Sales application shows where the Home screen images and some of the button icon images have been replaced with alternative images.

6

WindowsMobileSalesFunctionEnablingThe Windows Mobile Sales application consists of seven main functional areas:

• Accounts• Contacts• Activities• Leads• Opportunities• Sales Documents• Analytics

Depending on organizational needs, any of these functional areas may be disabled through the XML-based Mobile Sales configuration file, which is called SybaseCRM.Configuration_template.xml and located under the Templates folder in the Mobile Sales installation folder. Within the configuration file, a property to enable or disable each functional area is defined. All the functional areas are enabled by default. For example:

<!-- Enabled Functional Areas -->

<SYS_Enable_Accounts>true</SYS_Enable_Accounts>

<SYS_Enable_Contacts>true</SYS_Enable_Contacts>

<SYS_Enable_Activities>true</SYS_Enable_Activities>

<SYS_Enable_Leads>true</SYS_Enable_Leads>

<SYS_Enable_Opportunities>true</SYS_Enable_Opportunities>

<SYS_Enable_SalesDocuments>true</SYS_Enable_SalesDocuments>

<SYS_Enable_Analytics>true</SYS_Enable_Analytics>

<SYS_Enable_Interactions>true</SYS_Enable_Interactions>

To disable a function, set its configuration value to false. For example, to disable the Sales Documents functionality:

<SYS_Enable_SalesDocuments>false</SYS_Enable_SalesDocuments>

Note: “true” and “false” are case sensitive and must be entered in lower case.

This action removes the Sales Document functionality from the Home screen and any related Sales Document functions on the Inspect screens of Accounts and Contacts. Screen shots of the Home screen with Sale Documents enabled and disabled are shown on the top of page 7.

7

The configuration file also contains a set of parameters that allows the order of the functional areas on the Home screen to be changed. These configuration settings show the Windows Mobile Sales default configuration settings:

<!-- The order the items appear on the home screen from 0 (first position) to 7 last position -->

<SYS_AccountsPosition>0</SYS_AccountsPosition>

<SYS_ContactsPosition>1</SYS_ContactsPosition>

<SYS_ActivitiesPosition>2</SYS_ActivitiesPosition>

<SYS_LeadsPosition>3</SYS_LeadsPosition>

<SYS_OpportunitiesPosition>4</SYS_OpportunitiesPosition>

<SYS_SalesDocumentsPosition>5</SYS_SalesDocumentsPosition>

<SYS_AnalyticsPosition>6</SYS_AnalyticsPosition>

<SYS_RecentsPosition>7</SYS_RecentsPosition>

The screen shots show a gap in the button list where Sales Documents has been disabled. The gap can be removed by adjusting the position settings and changing the Sales Document position to appear at the end of the button list:

<SYS_SalesDocumentsPosition>7</SYS_SalesDocumentsPosition>

<SYS_AnalyticsPosition>5</SYS_AnalyticsPosition>

<SYS_RecentsPosition>6</SYS_RecentsPosition>

8

This action results in the Home screen appearing like this:

As with the branding customization, changing the Mobile Sales configuration file requires that the deployable CAB file be rebuilt to include the new version of the file. Alternatively, you can use a deployment and configuration tool such as Afaria® after installation.

WindowsMobileSalesScreenLayoutandDataBindingThe Windows Mobile Sales application uses Resco XML screen template files, which define the layouts for all

the major view, inspect and act screens. The template files are read at runtime, and the screen layouts are built dynamically at runtime. The templates are pure XML and may be modified to change screen layout, data binding and formatting. The XML files are bundled as part of the deployed application and therefore may be updated and/or replaced, thus changing the screen layouts when the Mobile Sales Application needs to be recompiled.

Resco templates can be edited using the Resco MobileForms Toolkit 2010 AdvancedList Designer or any text editing tool. If templates are modified, then either the deployable CAB file must be rebuilt or the new templates must be deployed to the devices, replacing the default templates, using Afaria or a similar product. Note: Windows Mobile Professional and Standard platforms have different versions of each template because the screen layouts and resolutions are different.

To find out more about Resco usage, see www.resco.net/developer/support/help/index.html.

Template file naming conventionIn some circumstances, the Resco templates for a single screen are duplicated to support different layouts for

various localizations/languages. The Mobile Sales application automatically loads the correct localized XML template based on the device locale. If the correct localized version of the template cannot be found, then the default English (en) template is used.

9

The template file name format isTemplateName.xx.xml, where xx represents the two-character culture code:

• TemplateName.en.xml = English• TemplateName.fr.xml = French• TemplateName.de.xml = German• TemplateName.es.xml = Spanish

Anatomy of a View list templateFor a View list, the Resco AdvancedList XML template consists of row templates, which can in turn contain cell

templates. Lists usually have five row templates. They are:

1. DetailRowdefines the standard row:

2. DetailRowSelected defines the row layout where it has been selected. In this example, the selected template has a different layout than the standard row, in addition to being highlighted:

3. GroupHeaderdefines the group header row that is inserted when the list is displayed in grouped mode. Do not modify this row template:

4. GroupHeaderSelectedis the selected row template of the GroupHeader. Do not modify this row template:

5. NoRecordsFound defines the row template shown when no records are available or meet the filter/search criteria

the user specifies. Do not modify this row template:

Anatomy of an Inspect templateFor an Inspect form, the Resco AdvancedList template consists of row templates, which can in turn contain cell

templates. All inspect templates contain default row templates:

• InfoRow – Displays the pending banner when waiting for confirmation from SAP• ErrorRow – Displays SAP error messages associated with the current inspect object• WarningRow – Displays SAP warning messages associated with the current inspect object• CERow – Displays SAP custom enhancement fields

Additional row templates are used to display the object data. These typically consist of two cells, one of which contains a label, and the other the data binding value. For example, in this row template extract that shows the SAP ID for the current object, the first cell is the data property binding and the second cell holds the label text — in this case a translatable property because it starts with “_”:

<RowTemplate>

<Property Name=”Name” Value=”IDRow” />

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”TextFont” Value=”Tahoma, 8.25pt, style=Bold” />

<Property Name=”Bounds” Value=”80,0,-1,14” />

<Property Name=”CellSource” Value=”&quot;#{Id}&quot;” />

<Property Name=”Name” Value=”Id” />

10

</Cell>

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”0,0,80,14” />

<Property Name=”CellSource” Value=”&quot;_ID:&quot;” />

<Property Name=”Name” Value=”IDLabel” />

</Cell>

<Property Name=”Height” Value=”14” />

<Property Name=”BackColor” Value=”Transparent” />

</RowTemplate>

At run time, the #{Id} data item will contain the ID proprty value of the bound object. The label will contain the translation of _ID . The Bounds property specifies the location of the cell — the first two numbers represent the x,y coordinates relative to the row position, and the second two numbers represent the width and height. In this example, the width is set to -1, which means that the cell will expand to the right-most edge of the List control.

Additional items can be added using the same approach. That is, any additional labels must be added to the properties files if translations are required. The next example shows how a row template can contain multiple cells. In this example, address elements are added to a single row template.

<RowTemplate>

<Property Name=”Name” Value=”AddressRow” />

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”55,0,140,14” />

<Property Name=”CellSource”

Value=”&quot;#{AddressLine1}&quot;” />

<Property Name=”Name” Value=”AddressLine1” />

</Cell>

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”55,14,140,14” />

<Property Name=”CellSource”

Value=”&quot;#{AddressLine2}&quot;” />

<Property Name=”Name” Value=”AddressLine1” />

</Cell>

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”55,28,140,14” />

<Property Name=”CellSource” Value=”&quot;#{City}&quot;” />

<Property Name=”Name” Value=”AddressLine2” />

</Cell>

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”55,42,140,14” />

<Property Name=”CellSource” Value=”&quot;#{PostalCode}&quot;” />

<Property Name=”Name” Value=”PostalCode” />

</Cell>

</RowTemplate>

11

The next example shows a more complex example of binding multiple data items and static text into a single UI field.

<RowTemplate>

<Property Name=”Name” Value=”PhoneRow” />

<Cell Type=”Resco.Controls.AdvancedList.LinkCell”>

<Property Name=”Bounds” Value=”55,0,-1,14” />

<Property Name=”CellSource” Value=”&quot;#{PhoneNumber}

_Ext:#{PhoneExtension}&quot;” />

<Property Name=”Name” Value=”PhoneNumber” />

</Cell>

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”0,0,55,14” />

<Property Name=”CellSource” Value=”&quot;_Phone:&quot;” />

<Property Name=”Name” Value=”PhoneLabel” />

</Cell>

<Property Name=”Height” Value=”14” />

<Property Name=”BackColor” Value=”Transparent” />

</RowTemplate>

At runtime this template code will be rendered as:

Points to note:

• This is a link field style, so clicking will cause the number to be called (without the extension)• The Bounds property specifies the item location.• The item is a composite field made from the PhoneNumber property and the PhoneExtension property of an

Account.• Localised static text _Ext: is kept in the final rendered field. The data binding code automatically attempts to

translate any text starting with an underscore.• The Label is a text cell that is also translated automatically, as the string starts with an underscore.

A cell may contain a format property called FormatString:

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”TextFont” Value=”Tahoma, 8.25pt, style=Regular” />

<Property Name=”Alignment” Value=”TopRight” />

<Property Name=”FormatString” Value=”{0:t}” />

<Property Name=”Bounds” Value=”130,14,-1,14” />

<Property Name=”CellSource” Value=”&quot;#{StartTime}-

#{EndTime}&quot;” />

<Property Name=”Name” Value=”Cell4” />

</Cell>

12

As each field is bound to the UI, the formatting will be applied to the underlying object property. Supported formats are:

Date/TimeFormats

d Short date 6/15/2009 (en-US)

D Long date Monday, June 15, 2009 (en-US)

t Short time 1:45 PM (en-US)

T Long time 1:45:30 PM (en-US)

f Full date/time pattern (short time) Monday, June 15, 2009 1:45 PM (en-US)

dddd Full name of the day of the week Monday (en-US)

g General date/time pattern (short time) 6/15/2009 1:45 PM (en-US)

G General date/time pattern (long time) 6/15/2009 1:45:30 PM (en-US)

NumericFormats

C2 A currency value 123.456 (en-US) $123.46

F2 Integral and 2 decimal digits with optional negative sign

1234.567 (en-US) 1234.57

F Integral and decimal digits with optional negative sign

1234.567 (en-US) 1234.57

FO Integral and 0 decimal digits with optional negative sign

1234.567 (en-US) 1234

N Integral and decimal digits, group separators and a decimal separator with optional negative sign

1234.567 (en-US) 1,234.57

N2 Integral and 2 decimal digits, group separators and a decimal separator with optional negative sign

1234.567 (en-US) 1,234.57

NO Integral and 0 decimal digits, group separators and a decimal separator with optional negative sign

1234.567 (en-US) 1,234

The formatted values are localized based on the device locale. For example, if the locale is fr-FR, then the formatted text for 123.456 (C2, fr-FR) appears as 123,46 €. If the locale is en-US, then 123.456 (en-US) appears as $123.46.

Anatomy of an Act templateFor an Act (edit) form, the Resco DetailView template consists of Item templates, one for each editable item:

<Item Type=”Resco.Controls.DetailView.ItemTextBox”>

<Property Name=”WordWrap” Value=”True” />

<Property Name=”ItemBorder” Value=”Flat” />

<Property Name=”Label” Value=”_Description:*” />

<Property Name=”LabelAlignment” Value=”Left” />

<Property Name=”Height” Value=”17” />

<Property Name=”AutoHeight” Value=”True” />

<Property Name=”LabelWidth” Value=”70” />

<Property Name=”Name” Value=”Description” />

<Property Name=”TextBackColor” Value=”Window” />

</Item>

13

Automatic translation is supported for the template labels; that is, from _Description:*. The Name property determines what property belonging to the object being bound is placed into the editable control. The DetailView items appear sequentially on the form and have only a height property and not an x,y location property as supplied by the cells in the Advanced list examples.

These edit controls are supported:

• ItemTextBox – standard text control• ItemComboBox – drop down list style• ItemDateTime – drop down calendar, optionally with a time picker.

ItemComboBoxes are populated from SAP customization data; however, these are limited to a subset of CRM data:

• Activity Status• Activity Category• Activity Type• Lead Status• Sales Document Type• Sales Document Type Code• Sales Document Status• Opportunity Status• Opportunity Stage• Opportunity Type• Country• Country Code• Boolean• User Position• User• Sales Team Members• Sales Teams

If additional dynamic lists are needed, then a code change will be required to support the new dynamic list.

The search parameter forms also use the Resco DetailView format templates.

CuStOm COdiNg: addiNg a New prOCeSS tO wiNdOwS mOBiLe SaLeSSometimes these customizations are not flexible enough. In those cases — for example, a new process type may

need to be displayed within the client application — it is possible to modify the client C# code of the Mobile Sales application.

TheVIAModelThe VIA model is an information architecture for mobile business applications based on a limited set of UI building

blocks — the View, Inspect and Act components — that enable quick definition and customization of mobile solutions.

View components serve as navigational entry points into the work of business users (such as work list, search, calendar, my favorite items, object browser, KPI dashboard or inventory manager). The highly optimized View components can be re-used across applications, depending on user role and application context.

The Inspect component is a one-design-fits-all approach. The component is adaptable to display simple overviews, composite overviews, item lists and task lists. It can be used for simple or multi-faceted contexts. This UI pattern should standardize how business users inspect business data.

14

Act components allow the safe and consistent integration of transactional operations by specifying a framework for the action lifecycle, multi-step actions and optional device-specific services such as note taking, image capturing and voice recording. Archetypical (such as form entry, create, classify) or re-usable actions (such as record time and get signature) might evolve over time.

As the Work Zooming Model shows, any mobile work goes through the View and Inspect stages of orientation and searching before coming to the detailed inspection in which the user can finally take action. Of course, any interrelation and shortcut can be introduced to accelerate interaction, but the fundamental application structure will be maintained.

The Work Zooming Model

Apart from structuring the application into clear interaction levels, the VIA model defines components that are optimized to meet the requirements of each level. View components are optimized to identify, find and select relevant information objects. Inspect components provide an optimized view of a single object of interest, focusing either on a handy summary or in-depth detail, or even combining both. Act components guide the user through transactions executed on the business data and facilitate the handling of such data by providing best practice and input support.

Pre-requisitesBefore starting, ensure that you have the proper software installed. You’ll need:

• Microsoft Visual Studio 2008 Standard Edition version 9.0.30729 or above with C# capability• Windows Mobile 6 Professional and Standard Software Development Kits• Microsoft ActiveSync 4.5.0• Resco Mobile Forms Toolkit 2010 or above (optional)• Sybase Mobile Sales 1.1 Source Code

VisualStudioMobileSalesProjectOverviewThe Mobile Sales application consists of one solution, SybaseCRM. This solution contains four C# projects.

• SybaseCRMControlscontains common custom controls used throughout the Mobile Sales application.

• SybaseCRMProBooterand SybaseCRMStdBooter are simple bootstrap projects used to launch the Mobile Sales application on the respective Windows Mobile Professional or Windows Mobile Standard platforms. Keeping the application’s EXE as small as possible and putting all the forms, code, resources and data in managed DLLs reduces the amount of virtual memory the application uses inside its 32MB process slot, while taking advantage of memory outside the slot in the 1GB shared memory area. These projects also hold the deployable files and resources for example graphic, configuration and Resco XML screen template files.

15

• SybaseCRMProandSybaseCRMStd contain the main implementation of the Windows Mobile Sales application. These two projects share common C# code files, which contain the non-device/UI-specific code.

UIFrameworkThe Mobile Sales application uses the Sybase AAT classes to provide low-level UI component management and

caching. The AAT framework controls all UI components and their contexts. The same component can have multiple contexts.

This structure results in higher performance, because if the developer queries for a component that was previously instanced, the framework will return this instance (care must be taken to reset the control values as necessary). A new instance of a component can be created at any point if required.

AAT holds all components that were shown to the user and not explicitly closed within a stack. This stack represents the Z-order of the components. If a user closes a component, the component gets removed from the stack and the underlying component comes to the front automatically.

The Mobile Sales project references the iAnywhere.ATT.dll assembly, which provides these major classes:

• Framework.This class is the main entry point for every application build on top of AAT. The class defines all base methods for controlling the screen flow of an application. This is a static class and so cannot be inherited or instantiated.

• UIComponent.The UIComponent has to be seen as a single screen element. The Framework class maintains a stack of UIComponents.

• IController.This interface defines the main entry points for the Framework class to call into.

• IUIFactory. This interface is implemented in the custom UIFactory of the Mobile Sales application. Its methods are used for initializing all UIComponents during application runtime.

The Mobile Sales application contains only a few forms, because most of what would be implemented as forms are implemented using the AAT UIComponent.

addiNg a New prOCeSS Before implementing the UI, the new process business object and supporting SAP backend objects and BAPIs must

be created. To add a new process, several actions must be considered:

1. Create the View/List overview screen2. Create the View/List overview XML screen layout template3. Create the Inspect screen4. Create the Inspect XML screen layout template5. Create the Act/edit screen6. Create the Act XML screen layout template7. Add any new images and update the ImageManager to handle the new images8. Update the TemplateManager to handle the new XML templates9. Update the Navigation Class to allow navigation to the new screens10. Update the Home screen, adding a new button for the new process11. Add any localizable strings to the properties resources

In this example, a new process called Survey has been created. The walkthrough will demonstrate how to add the Survey process to Windows Mobile Sales.

16

CreatingaNewProcessViewScreenTo create a new View screen, two UI components must be created and added to the project: a UIComponent and a

Resco XML screen template.

CreatingtheRescoXMLTemplateAll the screens in the Windows Mobile Sales application are defined in XML files. Resco controls then take these

XML files and render the UI based on their content. The Resco templates may be edited using either the Resco MobileForms Toolkit 2010 AdvancedList Designer or any text editing tool. Note: Windows Mobile Professional and Standard platforms have different versions of each template because the screen layouts and resolutions are different.

Template file naming conventionThe Resco templates may vary to support different localizations/languages. The TemplateManger class

automatically loads up the correct localized template based on the device locale. If the localized version of the template cannot be found, the default English (en) template is used.

The template file name format is TemplateName.xx.xml, wherexxrepresents the two character culture code:

• TemplateName.en.xml = English• TemplateName.fr.xml = French• TemplateName.de.xml = German• TemplateName.es.xml = Spanish

Creating a new View list template1. Open SybaseCRMProBooter (or SybaseCRMStdBooter) and navigate to folder Templates\UI\Pro or Templates\UI\Std (the Standard edition is not shown in

the diagram).

3. Find the TemplateList.en.XML file, select Copy and paste it into Templates\UI\Pro (or Templates\UI\Std).

4. Rename the newly created Copy of TemplateList.en.xml to SurveyList.en.xml. Ensure the Copy to Output Directory is set to Copy if Newer.

5. Right-click SurveyList.en.xml, select Open With and select XML Editor.

Modifying a View list templateThe Resco template consists of row templates, which can in turn contain cell templates. Generally for lists there are

five row templates:

1. DetailRowdefines the standard row:

2. DetailRowSelecteddefines the row layout where it has been selected. Here the selected template has a different layout than the standard row and is highlighted:

3.GroupHeader defines the group header row inserted when the list is displayed in grouped mode. Do not modify this row template:

17

4.GroupHeaderSelectedis the select row template of the above GroupHeader. Do not modify this row template:

5. NoRecordsFounddefines the row template shown when no records are available or meet the filter/search

criteria specified by the user. Do not modify this row template:

Modifying the data bindingThe Survey list should display the survey name, the city and state where the survey is to take place:

In the XML document, find the DetailRow template:

<Property Name=”Name” Value=”DetailRow” />

The first Cell template is:

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”TextFont” Value=”Tahoma, 8.25pt, style=Bold” />

<Property Name=”Bounds” Value=”30,0,-1,14” />

<Property Name=”CellSource” Value=”&quot;#{XXXX}&quot;” />

<Property Name=”Name” Value=”Cell1” />

</Cell>

The Bounds property specifies the location and size of the cell. The first two numbers specify the x,y location within the row template for the top left corner. The next two numbers specify the width and height. Specifying -1 fills the available space.

CellSource specifies which property we want to bind to the cell. In the template, a placeholder is shown as #{XXXX}. The XXXX should be replaced with the survey name:

<Property Name=”CellSource” Value=”&quot;#{Name}&quot;” />

The second cell in the row template needs to show the city and the state. This could be done with two cell templates or, in this case, for neatness of layout, a compositie cell will be defined:

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”30,14,-1,14” />

<Property Name=”CellSource” Value=”&quot;#{City}, #{State}&quot;” />

<Property Name=”Name” Value=”Cell2” />

</Cell>

The #{XXXX} is replaced at runtime by the data binder. Anything else placed within the start and end &quot; will appear as is in the final representation of the cell. In the expression #{City}, #{State}, the city and state names will be substituted, but the comma will remain as static text, so the final string will read “Dublin, CA”, where “Dublin” and “CA “are from the SAP back end and the comma is static text from the template.

18

Finally, update the image cell, which holds the dynamic icon image to contain DynamicSurveyIcon in the Name field:

<Cell Type=”Resco.Controls.AdvancedList.ImageCell”>

<Property Name=”ImageListIndex” Value=”-1” />

<Property Name=”AutoTransparent” Value=”true” />

<Property Name=”AutoResize” Value=”true” />

<Property Name=”Bounds” Value=”6,6,16,16” />

<Property Name=”CellSource” Value=”&quot;-1&quot;” />

<Property Name=”Name” Value=”DynamicSurveyIcon” />

</Cell>

The DetailRowSelected row template should also be updated to match the DetailRow with regards to CellSource properties.

Creating a new Inspect templateNext, a template must be created to support the Inspect screen. This process is similar to that used to create the

ListView template.

1. Open SybaseCRMProBooter (or StdBooter) and navigate to folder Templates\UI\Pro (or Templates\UI\Std).2. Find the TemplateInspect.en.XML file, select Copy and paste it into Templates\UI\Pro (or Templates\UI\Std).3. Rename the newly created Copy of TemplateInspect.en.xml to SurveyInspect.en.xml. Ensure the Copy to Output

Directory is set to Copy if Newer.4. Right-click SurveyInspect.en.xml, select Open With and select XML Editor.

Modifying an Inspect templateThe Resco template is made up of row templates, which can in turn contain cell templates. All Inspect templates

must contain certain default row templates:

• InfoRow – Displays the pending banner when waiting for confirmation from SAP.• ErrorRow – Displays SAP error messages associated with the current inspect object.• WarningRow – Displays SAP warning messages associated with the current inspect object.• CERow – Displays SAP custom enhancement fields.

Additional row template are used to display the object data. These typically consist of two cells, one of which contains a label, and the other the data binding value. For example, in this row template extract that shows the SAP ID for the current object. The first cell is the data property binding and the second cell holds the label text — in this case a translatable item, because it starts with “_”:

<RowTemplate>

<Property Name=”Name” Value=”IDRow” />

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”TextFont” Value=”Tahoma, 8.25pt, style=Bold” />

<Property Name=”Bounds” Value=”80,0,-1,14” />

<Property Name=”CellSource” Value=”&quot;#{Id}&quot;” />

<Property Name=”Name” Value=”Id” />

</Cell>

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”0,0,80,14” />

<Property Name=”CellSource” Value=”&quot;_ID:&quot;” />

<Property Name=”Name” Value=”IDLabel” />

</Cell>

<Property Name=”Height” Value=”14” />

<Property Name=”BackColor” Value=”Transparent” />

<RowTemplate>

19

The #{Id} is the Id data item and the the label will contain the translation of _ID . Adding a new row template to show the Name of the survey assumes that the survey object has a Name property. Cut and paste the row template and change ID to Name:

<RowTemplate>

<Property Name=”Name” Value=”NameRow” />

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”TextFont” Value=”Tahoma, 8.25pt, style=Bold” />

<Property Name=”Bounds” Value=”80,0,-1,14” />

<Property Name=”CellSource” Value=”&quot;#{Name}&quot;” />

<Property Name=”Name” Value=”Name” />

</Cell>

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”0,0,80,14” />

<Property Name=”CellSource” Value=”&quot;_Name:&quot;” />

<Property Name=”Name” Value=”NameLabel” />

</Cell>

<Property Name=”Height” Value=”14” />

<Property Name=”BackColor” Value=”Transparent” />

<RowTemplate>

The properties resource file already contains a translation for Name, so we don’t need to add a new item — it will be translated using the existing translations. Additional items can be added using the same approach. Any additional labels must be added to the properties files if translations are required. The next items may be added; in this example, address elements are added to a new row template.

<RowTemplate>

<Property Name=”Name” Value=”AddressRow” />

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”80,0,140,14” />

<Property Name=”CellSource”

Value=”&quot;#{AddressLine1}&quot;” />

<Property Name=”Name” Value=”AddressLine1” />

</Cell>

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”80,14,140,14” />

<Property Name=”CellSource” Value=”&quot;#{City}&quot;” />

<Property Name=”Name” Value=”AddressLine2” />

</Cell>

<Cell Type=”Resco.Controls.AdvancedList.TextCell”>

<Property Name=”Bounds” Value=”0,0,80,14” />

<Property Name=”CellSource” Value=”&quot;_Address:&quot;” />

<<Property Name”Name” Value=”AddressLabel” />

</Cell>

<Property Name=”Height” Value=”28” />

<Property Name=”BackColor” Value=”Transparent” />

<RowTemplate>

20

UpdatingtheTemplateManagerThe TemplateManager class loads and caches the Resco XML templates used by the Windows Mobile Sales

application. Additional functionality handles on-device detail view personalization.

The TemplateManager.cs file is found under the Templates folder in the SybaseCRMPro/SybaseCRMStd projects. The TemplateManager.cs file is shared across both platforms, so although it appears under the two projects, there is only one physical source file.

A public enumeration provides a discrete list of all the available templates in the Windows Mobile Sales application. New enumeration items should be added (see bold items):

//define enumpublic enum TemplateType{ //************************************************** //Survey //************************************************** SurveyView, SurveyInspect, //************************************************** //Account //************************************************** AccountView, AccountInspectDetail,

The SetTemplate method must be updated to handle the new enumerations (see bold items):

internal static void SetTemplate( Resco.Controls.AdvancedList.AdvancedList advancedListView, TemplateType templateType) { switch (templateType) { //************************************************** //Survey //************************************************** case TemplateType.SurveyView: case TemplateType.SurveyInspect: //************************************************** //Account //************************************************** case TemplateType.AccountView: case TemplateType.AccountInspectDetail:

GetTemplateName, which maps the enumerations to the template file names, must be updated. In this case, SurveyList and SurveyInspect need to be added. Note that we don’t need to specify the locale or extension; the template loader handles this automatically.

internal static string GetTemplateName(TemplateType templateType)

{ switch (templateType) { //************************************************** //Survey //************************************************** case TemplateType.SurveyView: return “SurveyList”; case TemplateType.SurveyInspect: return “SurveyInspect”; //************************************************** //Account //************************************************** case TemplateType.AccountView: return “AccountList”;

Save the TemplateManager and check for compilation errors.

21

update the imagemaNager CLaSSTo show the correct icons on the ListView, the ImageManager class must be updated to handle the new Survey

process. First a new method, which will cache the survey icon along with error and warning icons, must be added. Open ImageManager.cs, which can be found under the Resources folder.

Add a new static ImageList variable, which will hold this list of images used by the survey view. For example:

protected static ImageList _SurveyTypeImageList;

Add a new method that will populate the Survey image list with the correct images:

/// <summary>/// Setup the the imagelist used by the Survey Business Object/// </summary>/// <returns>A populated ImageList</returns>internal static ImageList GetSurveyTypeImageList(){ if (_SurveyTypeImageList == null) { _SurveyTypeImageList = new ImageList(); _SurveyTypeImageList.Images.Add(GetBitmapSetSize(“Surveys.png”,

_SurveyTypeImageList)); //loads 16x16 or 32x32 depending on current DPI

_SurveyTypeImageList.Images.Add(GetBitmap(“error.png”)); //loads 16x16 or 32x32 depending on current DPI

_SurveyTypeImageList.Images.Add(GetBitmap(“warning.png”)); //loads 16x16 or 32x32 depending on current DPI } return _SurveyTypeImageList;}

The overloaded method GetImageList needs to access the GetSurveyTypeImageList. Add this code to the GetImageList(Object aBO) variant:

if (aBO is Survey){ return GetSurveyTypeImageList();}

And this code to the GetImageList(string cellName) variant:

if (cellName.Contains(“Survey”)){ return GetSurveyTypeImageList();}

These methods are used when setting the image lists associated with the dynamic image cell from the UIHelper class.

Finally, the GetImageIndex(DataRow aDR) needs to be updated to handle the survey object type.

22

else if (aBOT == BusinessTransactionObject.SURVEY_TYPE){ //If the BO is in an error start then show the error icon takes

precedence so must appear first if (CheckForError(aDR[TableFields.STATUS])) { return “1”; } //If the BO is synched and has messages then we have warnings, so show

warning triangle if (CheckForWarning(aDR[TableFields.STATUS])) { return “2”; } //Otherwise show the default icon. return “0”;}

Create the View ui COmpONeNtNext, we must create the View UI component. This component acts as the container for the Survey list template

just created and provides navigation, searching and filtering. The UI components have two parts: one that is different between platforms, and an implementation component that contains the code and is shared between platforms.

The first step is to create the platform-specific UI component. Navigate to the Forms\Pro folder in the SybaseCRMPro project. Here a template View UI component called TemplateView.cs can be copied and renamed to SurveyView.cs

Once copyed and renamed, the class names must be modified to reflect the name we want to access. Right-click on the SurveyView.cs file and select the ViewCode menu option. Little code is contained in the UI class — this new Survey list class descends from the BaseView class, which provides common functions across all views. Change the class name and the default constructor method to SurveyView.

internal partial class SurveyView : BaseView

{ #region ctor public SurveyView() { InitializeComponent(); //init() defined in .Shared class init(); }

#endregion

Don’t worry about compilation errors at this stage, because the .shared class has not yet been created. Save and close SurveyView.cs.

23

The UI components also have a “designer” file, which contains the details of the controls that belong to it. Generally this file should not be edited; however, it must be renamed to match the SurveyView class just created. Right-click the SurveyView.designer.cs file and select View Code from the context menu. Change the class name to SurveyView:

partial class SurveyView { /// <summary> /// Required designer variable. /// </summary>

private System.ComponentModel.IContainer components = null;

Now that the UI component has been created, the shared C# implementation file can be created. Navigate to the Forms\Shared folder in the SybaseCRMPro project and locate TemplateView.Shared.cs. Copy and rename TemplateView.Shared.cs to SurveyView.Shared.cs. The SurveyView.Shared.cs should be placed in the Shared folder if it is not located there already. Once renamed, right-click on SurveyView.Shared.cs and select View Code from the context menu. Change the class name to SurveyView:

namespace Sybase.CRM.UI.Forms

{ internal partial class SurveyView {

The rest of the changes will now be made in SurveyView.Shared.cs. Key places where changes are required are shown like this, with searchable comments:

• ** MODIFICATION REQUIRED ** Comments containing this text indicate that the code must be modified or implemented

• ** MODIFICATION OPTIONAL ** Comments containing this text indicate that code may be optionally modified or implemented

Failing to update or implement mandatory lines of code will result in a NotImplementedException being thrown at runtime.

From SurveyView.Shared.cs, with the cursor at the top of the source file, press Ctlr+f and search for the first MODIFICATION REQUIRED comment. This should find these lines of code in the init() method.

//set the Resco Template

// ** MODIFICATION REQUIRED ** TemplateManager.SetTemplate(lvItems, TemplateManager.TemplateType.AccountView);

throw new NotImplementedException(“Resco Template not set,see init() method”);

This is where the ListView template is set. The code needs to be modifed to refer to the SurveyView template and the throw removed. The code should now be:

//set the Resco TemplateTemplateManager.SetTemplate(lvItems, TemplateManager.TemplateType.SurveyView);

Still in the init method, the filter sort bar needs to be set up. First, the Show All filter name needs to be set. The Show All filter is used to reset any filters that may have been applied to the list and shows all the list items unfiltered.

24

From the template code, change the Name property to Properties.Resources.AllAccounts. to Properties.Resources.AllSurveys.

This change could be hard coded as a string literal; however, it is better practice to use the application resources. In this way, All Surveys can be translated and appear correctly for different languages. Therefore, adding the All Surveys as a resource string to each of the localized application resource files is necessary. The resource files can be found under the SybaseCRMPro project Properties folder. You will see the default resource file with no language specified, then additional resource files for German (de), Spanish (es) and French (fr). To edit a resource file, simply double-click it from the Solution Explorer. Scroll to the end of the list of items and add the new property resource:

Add two new resources named Surveys and TITLE_STD_SURVEYS with values of Surveys and CRM Surveys respectively. These will be used by the Home screen and the View form titles. (The Windows Mobile Standard platform has a slightly different View form page title.) A title will be needed for the Inspect screen, which will be a singular representation of the new object (for example, Survey and TITLE_STD_SURVEY for the STD platform). Repeat the process for each language file, replacing the All Surveys and Surveys with a translated version if you have translations available. If no tranlsations are available, put the English version in each file, but make a note to get translations. Don’t forget to save each Resource file after update.

Return to the SurveyView.Shared.cs file and replace Properties.Resources.AllAccounts with Properties.Resources.AllSurveys and delete the comment referring to modification required. This property is used by the drop-down list for filtering the list of surveys.

Next, configure the fields by which the list may be sorted. Two items need to be set up for sorting:

// ** MODIFICATION REQUIRED ** Change this to reference the correct field namefilterSortBar.Sorter.AddMenuAction(new ActionSortByField { Name = Properties.Resources.Name, Form = this, FieldName = Settings.PROPERTYNAME_ACCOUNT_DISPLAY_NAME });

// ** MODIFICATION REQUIRED ** Change this to reference the correct field namefilterSortBar.Sorter.AddMenuAction(new ActionSortByField { Name = Properties.Resources.City, Form = this, FieldName = Settings.PROPERTYNAME_ACCOUNT_CITY, Group = true });

First, the sort Name, which will appear in the UI to the user, must be specified. In this example we will allow sorting by survey name. Second, the survey property/sort field, which specifies the actual sort, must be specified. This is done by setting the FieldName. All the field names are held in the Settings class and new fields should be added to this class; however, for simplicty, a local string literal can be used. The code should be modified like this:

filterSortBar.Sorter.AddMenuAction(new ActionSortByField { Name = Properties.Resources.Name, Form = this, FieldName = “Name” });filterSortBar.Sorter.AddMenuAction(new ActionSortByField { Name =

Properties.Resources.City, Form = this, FieldName = “City”, Group = true });

Note that the City sort has an optional additional parameter called Group. If Group is set to true, then the list will appear in a grouped format with collapsable group headers after it’s sorted.

25

Press Ctlr+f and search for the next MODIFICATION REQUIRED comment. This code should be found within the ApplyContext() method.

context = new ListContext{ObjectTypeDesired = typeof(Account) // ** MODIFICATION REQUIRED ** <-- Change this to reference the correct process name,SearchFields = new[] { “Name”, “City”} // ** MODIFICATION REQUIRED ** <-- Change this to reference the correct Field names};

This is where the context object is set up. ObjectTypeDesired should be changed to Survey. The SearchFields are used during a quick search text filtering; in this case our list shows “Name”, “City”so these can be left as they are. However, “State” should be added because our template references the state property. The code should be modified like this:

context = new ListContext{ ObjectTypeDesired = typeof(Survey) , SearchFields = new[] { “Name”, “City””, “State”}};

The context objects contains a DataTable of the fields required for the view. These fields are derived from the Resco templates; additional fields maybe specified as necessary and added to the ListViewFieldsAttributes. Additional nececessary fields can include data drive icons or additional searchable fields that are not shown in the UI directly.

The last change in the apply context is setting the lists default sort order. Search once again for the next MODIFICATION REQUIRED comment. You should find:

//default: sort SetSort(Settings.PROPERTYNAME_ACCOUNT_DISPLAY_NAME, false); //

** MODIFICATION REQUIRED ** <-- Change this to reference the correct Field name

In this example, the list initially is sorted by Survey Name, so change the code to this:

//default: sort by Survey Name field.SetSort(“Name”, false);

Press Ctlr+f and search for the next MODIFICATION REQUIRED comment. You should find this code within the GetNavBarText() method.

#if Smartphone // ** MODIFICATION REQUIRED ** Change this to reference the correct process name return Properties.Resources.TITLE_STD_ACCOUNTS + “ (“ + context.List.DefaultView.Count.ToString() + “)”;#else // ** MODIFICATION REQUIRED ** Change this to reference the correct process name return Properties.Resources.Accounts + “ (“ + context.List.DefaultView.Count.ToString() + “)”;#endif

26

GetNavBarText() provides the title of screen that is displayed to the user, along with the item count shown in parenthesis. Here the title needs to be changed to Surveys:

if Smartphone return Properties.Resources.TITLE_STD_SURVEYS + “ (“ + context.List.DefaultView.Count.ToString() + “)”;#else return Properties.Resources.Surveys + “ (“ + context.List.DefaultView.Count.ToString() + “)”;#endif

The View screen is now complete and can be hooked into the application.

pLuggiNg the New prOCeSS iNtO the hOme SCreeNTo access the new Surveys View screen, some form of navigation from the Home screen is required. For simplicity,

one of the existing buttons will be used to navigate to the new list. In a real implementation, the Home screen UI would require some redesign to accommodate the new button. In this case, we will change the Analytics button image and clicked code to link to the new Surveys process.

First, a new image should be added to the SybaseCRMProBooter project under the folder Resources\images. Each image is added in three sizes, which support different uses and varying screen dpi on different devices. Generally the images are 16x16, 32x32 or 64x64 pixels. The naming convention is to place the size of the image after the image name: Surveys_16.png, Surveys_32.png, Surveys_64.png.

From the Solution Explorer, right-click on the Resources\Images folder and select Add -> Existing Item…:

Select the files Surveys_16.png, Surveys_32.png and Surveys_64.png and add to the project. Right-click on the newly added image files and ensure that the Copy to Output Directory is set to Copy if Newer.

Right-click and select View Code on the Home.Shared.cs file, which can be found in the Forms\Shared folder. Press Ctrl + f and search for imageButtonAnalytics. Search for this line of code:

if (conf.SYS_Enable_Analytics) setButtonImages(imageButtonAnalytics, “analytics_32.png”, “analytics_64.png”);

Replace references to “Analytics” with “Surveys”:

if (conf.SYS_Enable_Analytics) setButtonImages(imageButtonAnalytics,

“Surveys_32.png”, “Surveys_64.png”);

27

Change the label belonging to the button by adding this line of code:

imageButtonAnalytics.TextDefault = Properties.Resources.Surveys+ “\r\n”;

The “\r\n” is added because all the button text values can cover two lines. In this case, the second line is empty.

Next, the analytics clicked event needs to be modified to open the surveys view screen and not the analytics screen. Open the Home.cs file, press Ctrl + f and search for imageButtonAnalytics_Click. The implementation makes a call to the Navigation class, which must be updated to handle the new surveys process. Open the Navigation.cs file, which can be found in the Forms folder in the SybaseCRMPro project. The file contains a region called Navigate Template, which contains a template of all the code required to navigate to the View, Inspect and Act UI components. A placeholder is used to represent the class name that will be replaced after the implementation. By default all the code is commented out. As each UI component is implemented to support View, Inspect and Act functions, the code may be commented back into the Navigate class. Find the Navigate Template region and copy and paste the whole region. Expand the region and review the code. Rename the region to Survey:

#region Survey

Select all the commented code in the Survey region and press Ctrl+h to open the Quick Replace dialogue window. Enter <<<Object Class Here>>> in the Find What box and Survey in the Replace With box. Check that the Look In drop-down menu is set to Selection and ensure the correct scope of the replace:

Click the Replace All button; 41 occurrences will be replaced. At the beginning of the region the method ShowSurveyView should now be commented out. Remove the comments around the ShowSurveyView method so the code reads like this:

static internal void ShowSurveyView(){ try { //show the waitcursor WaitCursor.Show(true);

//get the UI Component var uic = Navigation.GetScreenComponent(typeof(Forms.SurveyView));

28

//pass null for context uic.BringToFront(Framework.BaseForm.Text, ScreenComponent.ControlBoxType.Minimize, null, true, true); } catch (Exception ex) { Logger.LogException(ex);

Software.ShowErrorMessage(Properties.Resources.MSG_ERROR_Form_Load + “: “ + ex.Message); } finally { WaitCursor.Show(false); }}

The rest of the template code that remains commented will be used later. For now it can remain commented out.

Return to the Home.cs file. Update imageButtonAnalytics_Click and replace the original call to show Analytics calling the newly created Navigation.ShowSurveyView(); method.

You should be able to compile and run the application to test the survey changes.

The New Home Screen

Clicking in the Surveys button navigates to the Surveys ListView.

29

Survey View Screen

Create the iNSpeCt FOrmThe next step is to create the Inspect UI component, a read-only container for an individual Survey instance. The

UI components have two parts, one that is different between platforms and an implementation component that contains the code and is shared between platforms.

TheContextObjectThe SurveyContext object, which is used to provide the UI component’s context in relation to a specific Survey object

instance, must be created first. Navigate to the Forms\Context folder in the SybaseCRMPro project. Here a template context object is available to use as a starting point for the new SurveyContext object. Copy the TemplateContext.cs and paste it into the Context folder. This creates a new file called Copy of TemplateContext.cs. Right-click on Copy of TemplateContext.cs and select Rename from the context menu. Change the name to SurveyContext.cs. Right-click on the new file and select View Code from the pop-up context menu. Rename the class to SurveyContext:

internal class SurveyContext : InspectContext

Rename the constructors from TemplateContext to SurveyContext and modify it like this:

internal SurveyContext(){ init();}

and

internal SurveyContext(string synckey){ //Get the data currentBO = Survey.FindBySyncKey(synckey); init();}

30

Press Ctrl+H. This opens the Quick Replace dialogue window. Enter <<<Object Class Here>>> in the Find What box and Survey in the Replace With box:

Press the Replace All button to substitute the class name Survey into the placeholders in the template code.

Find the alternative constructor. Rename the method from TemplateConext to SurveyContext and remove the MODIFICATION REQUIRED comments:

internal SurveyContext(Sybase.CRM.BusinessObjects.Survey Obj){ //Get the data currentBO = Obj;

init();}

The RefreshData method must be updated to ensure that it refers to the survey object. The RefreshData method is used to refresh the currently referred-to object in the current context from the underlying database. The earlier search and replace will have handled this; however, it is necessary to remove the comments and verify that the search and replace is correct. Find the RefreshData method and remove the // ** MODIFICATION REQUIRED comments so that the method reads:

31

internal override void RefreshData(){ base.RefreshData();

if (currentBO == null) return;

if (currentBO is Survey) { //Get the data currentBO = Survey.FindBySyncKey(currentBO.SyncKey ); }}

The final update to the new survey context objects consists of implementing a property that will return a reference to the current business object — (Survey) in this case. Find the properties region in the SurveyConext.cs file and remove the // ** MODIFICATION REQUIRED comments so that the method reads:

internal Survey Survey{ get { if (currentBO is Survey) return (Survey)currentBO; return null; }}

TheInspectFormOnce the Survey context object has been created, the inspect UI component can be created from the

TemplateInspect.cs UI component and the TemplateInspectForm.shared.cs files.

Find the TemplateInspect.cs UI component under the Forms\Pro folder and copy and paste it back in the Forms\Pro folder. This creates a new UI component called Copy of TemplateInspect.cs. Rename Copy of TemplateInspect.cs to SurveyInspect.cs. Repeat the process for the TemplateInspectForm.shared.cs file.

Right-click on the SurveyInspect.cs file and select View Code from the context menu. In the code, press Ctrl+H, which opens the Quick Replace dialogue window. Enter TemplateInspect in the Find What box and SurveyInspect in the Replace With box. Press the Replace All button. Save the UI component. Right-click on the SurveyInspect.desginer.cs file and select View Code. Repeat the search-and-replace process as described.

Next, navigate to the Sharedfolder and open the SurveyInspect.shared.cs file. Repeat the search-and-replace process in the SurveyInspect.shared.cs code view. Don’t forget to save the UI component. At this point you should be able to compile the SybaseCRMPro project. There should be no errors.

While inside the SurveyInspect.shared.cs code, update the context variable to reference the SurveyContext class created earlier. Press Ctrl+H and enter TemplateContext in the Find What box and SurveyContext in the Replace With box. Press the Replace All button.

Repeat this search and replace in the Find What box. Enter <<<Object Class Here>>> and replace with Survey. Press the Replace All button.

32

The init method is called once per UI component lifetime, inluding the method to load the Resco XML template. The SetTemplate method needs to be uncommented and read like this:

TemplateManager.SetTemplate(lvItems,TemplateManager.TemplateType.SurveyInspect);

This line of code depends on the TemaplateManager having a a TemplateType called SurveyInspect. This was created earlier (see section “Creating a new Inspect template”).

The ApplyContext method is called each time the UI component is brought to the foreground. It ensures that the UI component shows, and it updates the rendering of the object being inspected. Find the ApplyContext method and remove the // ** MODIFICATION REQUIRED comments.

ApplyContext calls another method, GetFormTitle, which displays the UI component title that is based on the type of object being inspected. In the template, the GetFormTitle method is commented out. For the SurveyInspect UI component, this code needs to be uncommented too, so it reads like this:

internal static string GetFormTitle(Survey bo){ #if !Smartphone return Properties.Resources.Survey + “: “ + bo.Description; #else return Properties.Resources.TITLE_STD_SURVEY; #endif}

This method will show the word Survey and the description of the Survey in the UI component title.

Next, the postOpen method must be updated. The postOpen method runs code after the UI component has been displayed (opened) to the user. The idea is to give a perception of improved performance; that is, the user can start to inspect the object details before all the UI component set-up processing has been completed. Find the postOpen method and remove the commented code to mark the Survey object as recent.

protected override void postOpen(){ base.postOpen();

//mark item as a recent item context.Survey.MarkRecent(); //setup local menus SetupMenusEnabledState();}

The MarkRecent method is common to all business objects and ensures that any object inspected will appear in the recent items ListView.

The postOpen method also sets up the menus on the UI component in regards to enabling functions based the state of the business object (in this case, a Survey). This is done with the SetupMenusEnabledState method, which can be found just after the postOpen method. The code is commented out in the template code; remove the comments so the code reads:

private void SetupMenusEnabledState()

33

{ if (context.Survey == null) return;

//set for all editable menu’s #if !Smartphone mniEdit.Enabled = UIHelper.IsBOStateEditable(context.Survey.State); #else mniEditActivity.Enabled = UIHelper.IsBOStateEditable(context.Survey.State); #endif

//Setup Undo menu based on BO status BOUtil.SetupUndoChangesMenu(mniUndoChanges, context.Survey }

HookinguptheInspectUIComponentNow that the basic SurveyInspect UI component has been implemented, it needs to be connected to the

SurveyView UI component. Thus when a Survey in the View UI component is clicked, the correct Survey is shown in the SurveyInspect UI component.

Open the source code for the SurveyView.Shared.cs file and locate the ShowInspectForm method. First remove the calls to throw the NotImplementedException. Next, implement a method that returns the selected Survey from a ListView. This should be done in the UIHelper class, where a method template exists. View the code in UIHelper.cs and locate the comment Get selected Template Code. Copy the code and replace <<<Object Class Here>>> with Survey. You have created a new method called GetSelectedSurvey:

static internal Survey GetSelectedSurvey(AdvancedList lv){if (lv == null) return null;

Row row = lv.SelectedRow;

if (null == row) return null;

if (row.FieldCount < 2) return null;

return Survey.FindBySyncKey(row[row.FieldCount - 2].ToString());}

A navigation method is required to show the SurveyInspect UI component. Open the Navigatation.cs file and locate the Survey region. Find the Show Inspect Screen comment and comment in these methods, which are encapsulated with a “/* */” comment block:

• ShowSurveyInspect(string Id)

• ShowSurveyInspect(BusinessObjects.Survey obj)

• delegate void SurveyInspectDelegate(SurveyContext ctx);

• ShowSurveyInspect(SurveyContext ctx)

• OnSurveyInspectDelegate(SurveyContext ctx)

34

Return to the source code for SurveyView.Shared.cs and find the ShowInspectForm() method. Replace <<<Object Class Here>>> with Survey and remove the “/ ** MODIFICATION REQUIRED **” comments so the method reads:

internal override void ShowInspectForm(){ base.ShowInspectForm();

if (UIHelper.GetSelectedSurvey(lvItems) == null) { UIHelper.ShowErrorMessage(Properties.Resources.MSG_ERROR_PLEASE_MAKE_ SELECTION_GENERIC); return; }

Navigation.ShowSurveyInspect(UIHelper.GetSelectedSurvey(lvItems));}

Building and testing the application should now be possible, and the View and Inspect screens will be navigable. The Inspect screen should look similar to this:

Additional fields may be added to the Resco SurveyInspect.en.xml template to display additional fields as necessary.

35

Create the aCt ui COmpONeNtThe final step is to create the Act UI component, which is the editable UI component for an individual Survey

instance. As with all the forms in the Mobile Sales application, the Act UI component forms have two parts: the UI component part that varies between platforms, and an implementation component that contains the code and is shared between platforms. The Act form uses the same context object as the Inspect UI component.

Before creating the UI component, the CRM resource files need to be updated and the Create Survey and Edit Survey properties added. These actions allow the UI Component title to be localized for different languages, providing translations are provided. The resource files can be found in the SybaseCRMPro project Properties folder. To edit a resource file, double-click it from the Solution Explorer. Scroll to the end of the list of items and add the new property resource:

TheSurveyActUIComponentThe Survey Act UI component can be created from the TemplateAct.cs UI component and the TemplateActForm.

shared.cs code template files.

Find the TemplateAct.cs UI component in the Forms\Pro folder, copy and paste it back in the Forms\Pro folder. This creates a new form called Copy of TemplateAct.cs. Rename Copy of TemplateAct.cs to SurveyAct.cs. Repeat the process for the TemplateActForm.shared.cs file.

Right-click on the SurveyAct.cs file and select View Code from the context menu. In the code, press Ctrl+H, which opens the Quick Replace dialogue window. Enter TemplateAct in the Find What box and SurveyAct in the Replace With box; press the Replace All button. Save the UI component. Right-click on the SurveyAct.desginer.cs file and select View Code. Repeat the search-and-replace process.

Next, navigate to the Shared folder, open the SurveyAct.shared.cs file and repeat the search-and-replace process in the SurveyAct.shared.cs code view. You should now be able to compile the SybaseCRMPro project without errors.

While you’re inside the SurveyInspect.shared.cs code, update the context variable to reference the SurveyContext class. Press Ctrl+H and enter TemplateContext in the Find What box and SurveyContext in the Replace With box. Press the Replace All button. Find the ApplyContext method and replace <<<Object Class Here>>> with Survey. Remove the “/* ** MODIFICATION REQUIRED **” comments so the method reads:

if (context.Survey == null ){ //new activity currentFormType = FormType.New;

#if !Smartphone progressMeter1.MeterVisible = true; progressMeter1.TotalSteps = 1; #endif

//currentBizObj created later currentBizObj = null;

SetHeaderInfo(Properties.Resources.CreateSurvey, 1);}else {

36

//set the object currentBizObj = context.Survey;

currentFormType = FormType.Edit;

#if !Smartphone progressMeter1.MeterVisible = false; #endif //check if data is stale, if so, then refresh if (context.DataRefreshNeeded) context.RefreshData();

SetHeaderInfo(Properties.Resources.EditSurvey, 0);

}

This code decides if a new object (Survey) is being created; that is, context.Survey == null, or whether en existing object is being edited. Note the progress meter setup, which is used to give the user feedback on the progress through the object create process. In this case, there is a single step; in other cases, there may be more. Examine AccountAct.Shared.cs for an example where more than one step is required.

In the Survey example, only one step is required to create or edit a Survey. In other cases — for example, Account Create/Edit — multiple steps are required. The BaseAct class supports multiple steps and provides menus that perform Next, Previous or Cancel functions. In this case, when editing or creating a Survey object, there are only Save or Cancel options. The menu used for these two options is called mainMenuNextCancel. Here the Next portion is used as a Save option by changing the text to Save (code to handle the menu clicked event must also be added):

//show menu with save/cancelmniNext2.Text = Properties.Resources.Save; //SET MENU TEXT TO SAVEFramework.BaseForm.Menu = this.mainMenuNextCancel;

This code changes the text to the localized text for Save and switches the default menu on the base to the mainMenuNextCancel menu. The code to handle the saving of changes is placed in the DoNextClicked method, which is called from the BaseAct class when the menu is clicked. In this case, the code simply needs to save any changes. In the case of objects that consist of multiple steps to create/edit, the code will be much more complex. In this simple case, the DoNextClicked method should be modified to read:

protected override void DoNextClick(){ SaveChanges();}

The SaveChanges method is implemented in the BaseAct class and is common for all objects.

CreatingtheRescoDetailViewXMLTemplateAs with the View and Inspect forms, the data appearing on the Act forms is defined by a Resco XML template.

Unlike the previous examples, the Act forms use DetailView templates and not AdvancedList templates. The structures are similar; however, the control it is bound to is different. The TemplateEdit.en.xml template, located in the Templates folder, can be used as the basis for the new SurveyEdit.en.xml screen layout that needs to be created. Copy and paste the TemplateEdit.en.xml template into the Templates\UI\Pro folder. Rename the new Copy of TemplateEdit.en.xml to SurveyEdit.en.xml. Open the SurveyEdit.en.xml file in the XML editor. A few basic fields and examples of usage are included the template.

37

First, an ItemTextBox called label1 is used to hold the title for the edit screen. In this case, the Label property is set to “_Edit”. As with the other templates, the application attempts to translate any string starting with an underscore based on the application resource settings. The title label is set to false because it’s a constant value. A label ItemTextBox is not intended to bind data and must contain the word “label” in the Name property for the data binding function not to attempt to bind data into the field.

The next ItemTextBox holds a property called Name, which is used to bind the property from the object being bound to the DetailView. In this case, there is a property of an item called Name, whose Name is name, holding the value AddressLine1. Looking further down the XML, you will see the example for address:

<Item Type=”Resco.Controls.DetailView.ItemTextBox”> <Property Name=”ItemBorder” Value=”Flat” /> <Property Name=”Label” Value=”_Street:” /> <Property Name=”LabelAlignment” Value=”Left” /> <Property Name=”LabelWidth” Value=”70” /> <Property Name=”Name” Value=”AddressLine1” /> <Property Name=”TextBackColor” Value=”Window” /></Item>

This particular item consists of a label that is the translation of Street; the property that is bound from the object will be AddressLine1, as specified by the XML name property. Additional properties can be added using the XML snippet as a template.

UpdatetheTemplateManagerfortheDetailViewTemplateThe TemplateManager class is responsible for the DetailView and the AdvancedList Resco XML templates. In the

SybaseCRMPro/ SybaseCRMStd projects, open the TemplateManager.cs file found in the Templates folder.

The public enumeration TemplateType needs to be updated, adding an enumerate for the SurveyEdit (see bold):

public enum TemplateType{ //************************************************** //Survey //************************************************** SurveyView, SurveyInspect, SurveyEdit,

This update should already have been done for the View and Inspect forms.

The SetTemplate method must be updated to handle the new enumeration. This overloaded version of SetTemplate takes DetailView as the first parameter, not an AdvancedList as in the previous case. See bold:

internal static void SetTemplate(Resco.Controls.DetailView.DetailView aDetailView, TemplateType templateType){ switch (templateType) { //************************************************** //Survey //************************************************** case TemplateType.SurveyEdit:

//************************************************** //Account //************************************************** case TemplateType.AccountEdit:

38

The GetTemplateName, which maps the enumerations to the template file names, must be updated. In this case, SurveyEdit needs to be added. SurveyList and SurveyInspect were added earlier.

internal static string GetTemplateName(TemplateType templateType){ switch (templateType) { //************************************************** //Survey //************************************************** case TemplateType.SurveyView: return “SurveyList”; case TemplateType.SurveyInspect: return “SurveyInspect”; case TemplateType.SurveyEdit: return “SurveyEdit”; //************************************************** //Account //************************************************** case TemplateType.AccountView:

return “AccountList”;

Save the Template Manager and check for compilation errors.

HookuptheActUIComponentTo hook up the SurveyAct UI component with the rest of the Mobile Sales application, the Navigation class must

be updated to include the new SurveyAct UI component references. Open the Navigation.cs file and locate the Survey region. Locate the Show Act Screen comments and commenting in the commented-out Act code.

Once the Navigation class has been updated, the SurveyAct UI component can be used to create/edit a Survey. You can create or edit a Survey from several locations within the Mobile Sales application. The SurveyView UI component has two menu options: one to create and one to update a Survey. Open the SurveyView.Shared.cs code and locate the mniEdit_Click method. Remove the comments from // ** MODIFICATION REQUIRED ** and throw new NotImplementedException so the code reads:

private void mniEdit_Click(object sender, EventArgs e){ if (UIHelper.GetSelectedAccount(lvItems) == null) { UIHelper.ShowErrorMessage(Properties.Resources.MSG_ERROR_PLEASE_MAKE_ SELECTION_GENERIC); return; }

Navigation.ShowSurveyAct(UIHelper.GetSelectedSurvey(lvItems)); }

Locate the mniCreate_Click method and remove the comments and the throw new NotImplementedException so the code reads like this:

private void mniCreate_Click(object sender, EventArgs e){ Navigation.ShowSurveyAct();}

39

You can create/edit a Survey from the Survey Inspect screen; therefore, the respective menu item events must also be updated. Open the SurveyInspect.Shared.cs file and locate the mniEdit_Click method. Remove the comments from the // ** MODIFICATION REQUIRED ** so the code reads:

private void mniEdit_Click(object sender, EventArgs e){ Navigation.ShowSurveyAct(context); }

Locate the mniCreate_Click method and remove the throw new NotImplementedException so the code reads:

private void mniCreate_Click(object sender, EventArgs e){ Navigation.ShowSurveyAct();

}

The Inspect screens by default have the ability to Undo changes. The Undo changes code is handled by the mniUndoChanges_Click method. Locate the mniUndoChanges_Click method and comment in the code so it reads:

private void mniUndoChanges_Click(object sender, EventArgs e){ var status = context.Survey.State; ABOCallbackTypes cbt = ABOCallbackTypes.UPDATE;

//”undo” for IN_ERROR_NEW really is a delete from the database. if (status == Statuses.IN_ERROR_NEW) { DialogResult r = MessageBox.Show(Properties.Resources.MSG_ConfirmRemoveItem, Properties.Resources.TITLE_Confirm, MessageBoxButtons.YesNo, MessageBoxIcon. Question, MessageBoxDefaultButton.Button1); if (r == DialogResult.No) { return; } cbt = ABOCallbackTypes.DELETE; }

context.Survey.Cancel();

//Refesh the view to update the icon Software.SignalSurveyViewDataRefreshNeeded(context.Survey.SyncKey, cbt);

if (status == Statuses.IN_ERROR_NEW) { Close(); } else { //Refresh the data context.DataRefreshNeeded = true;

ApplyContext();

}

}

40

You may notice that the SignalSurveyViewDataRefreshNeeded method does not exist. This method forms part of the callback — event-driven UI updates.

CallbackImplementationThe CRM Mobile Sales application receives notifications from the Sybase Unwired Platform code whenever a

change is made to an MBO or when some application event occurs, such as when the SAP password expires or the subscription has been deleted. The callbacks are defined in the software.cs file.

To add the callback that notifies the Survey view that it must refresh some of the items it currently displays, open the software.cs file and navigate to #region View “ListView” refresh methods. At the end of the region, add this code to support Survey objects:

internal static void SignalSurveyViewListViewRefreshNeeded(){ SignalListViewRefreshNeeded(typeof(BusinessObjects.Survey));}

This method refreshes data from an in-memory item and does not cause database access.

A second method must be added for the times when an update has been made to the database and an in-memory object must be reread from the database to update the Survey ListView:

internal static void SignalSurveyViewDataRefreshNeeded(string syncKey, ABOCallbackTypes cbt){ SignalDataRefreshNeeded(syncKey, typeof(BusinessObjects.Survey), cbt);}

This code should be placed in #region View “Data” refresh methods.

Finally, a callback method is required to handle the background refresh for the Survey Inspect screens. Locate the Background refresh methods region and add:

internal static void SignalSurveyBackGroundRefresh(string synckey, ABOCallbackTypes cbt){ SignalBackGroundRefresh(synckey, typeof(BusinessObjects.Survey), cbt);}

FiNaL ui ChaNgeThe final UI change is to update the navigation drop-down menu that appears at the top of the View and Inspect

screens in the title bar. By default it displays this:

41

Although it’s possible to add additional items, in this example, the Sales Documents menu option needs to be replaced with Surveys. The Nav bar menu is configured in the BaseForm.cs code (one of the few forms in the application). Locate the BaseForm.cs file under the Pro folder, right-click and select View Code. Within the code, locate the InitNavBar() method and replace the entry for Sales Documents with this:

navBar.AddMenuAction(new NavAction(Properties.Resources.Surveys, NavAction.

NavActionType.Surveys, ImageManager.GetBitmap(“surveys.png”)));

Remove the condition if (conf.SYS_Enable_SalesDocuments) and move the navBar.AddMenuSeparator(); to just before the code that sets the analytics menu option.

The navigation bar also keeps track of objects visited and allows the user to jump back to a previously visited object. Items are added to the object history by the AddNavBarHistoryItem method. The AddNavBarHistoryItem method should be modified to handle Survey Objects:

internal void AddNavBarHistoryItem(Sybase.CRM.BusinessObjects.CRMABO aBO){ if (aBO is Sybase.CRM.BusinessObjects.Account) { navBar.PushNavScreen(new NavScreen(((Sybase.CRM.BusinessObjects.Account)aBO).DisplayName, NavScreen.NavScreenType.Account, aBO.SyncKey)) ; } else if (aBO is Sybase.CRM.BusinessObjects.Contact) ……… } else if (aBO is Sybase.CRM.BusinessObjects.Survey) { navBar.PushNavScreen(new NavScreen(((Sybase.CRM.BusinessObjects.Survey)aBO). DisplayName, NavScreen.NavScreenType.Survey, aBO.SyncKey)); } }

(This code has been abbreviated to save space in this document.)

Add Surveys to the NavActionType enumeration found in the NavAction Class within BaseForm.cs:

public enum NavActionType{ Home, Activities, Accounts, Contacts, Leads, Opportunities, SalesDocuments, Surveys, Analytics}

42

Update the ActionPerformed method in the NavAction Class to handle Surveys by adding this code to the switch statement:

case NavActionType.Surveys: if (Framework.GetCurrentScreen().GetType() == typeof(SurveyView)) return;

BaseForm.FireNavigatingAwayMethod(); Navigation.ShowSurveyView();

break;

Add Surveys to the NavScreenType enumeration found in the NavScreen Class within BaseForm.cs:

public enum NavScreenType{ Account, Contact, Activity, Opportunity, Lead, SalesDoc, Interaction, Survey, Employee}

Update the Goto method in the NavScreen Class to handle Surveys by adding this code to the switch statement:

case NavScreenType.Survey: BaseForm.FireNavigatingAwayMethod(); Navigation.ShowSurveyInspect(pk1);

break;

Compile and run the application. The navigation drop-down menu should now include Surveys:

43

CuStOm eNhaNCemeNtS (Ce)All mobile CRM customizations are described and defined in ConfigurationGuide—MobileGateway1.0, which is

available from the SAP Service Marketplace. Any customization defined in the Mobile CRM customization sections are automatically handled by the standard Sybase Mobile Sales for SAP CRM application.

Custom enhancements allow CRM developers to deliver attributes associated with back-end CRM entities that are not exposed in the standard ESDMA that ships with CRM Mobile Sales. For example, the back-end CRM schema might have the attribute “language” associated with the partner object, but in the standard ESDMA, no such attribute is exposed. Using CE tables, CRM developers can make this attribute available and deliver it to the mobile device, and this can be done with no need either to change the ESDMA or adjust the data entities that are mobilized on the device.

To do this, CRM developers need to create (or modify existing) BADIs. Generally, this process would be performed by CRM functional experts, because it requires a detailed understanding of the CRM system.

To understand this process, it is necessary to gain an insight into the way data is pushed from CRM to DOE, and then how this flow can be adjusted to allow additional fields or attributes to be inserted at the appropriate places. This diagram is an overview of the data flow from CRM to DOE (and then to the DOE Connector, or DOE-C, and the mobile device).

CRM has its own data schema/model; DOE uses a data schema that ultimately maps into the ESDMA used by CRM Mobile Sales. The BAPI wrappers allow CRM/DOE developers to map data from CRM into the data schema used by DOE (and the device).

The DOE schema reflects the CRM application capabilities most required by mobile device users, but this is not enough to support all customer scenarios. To allow for some extensibility, additional data entities have been introduced into the standard schema. These entities, which are the CE tables, can be used to deliver additional data that is not covered by the existing entities to the device. However, this process is not automatic: some coding is necessary. The standard schema includes several of these tables, which are associated with the main objects in the standard ESDMA. For example, one CE table is associated with the main Business Partner (BUPA) object; another CE table is associated with each of the transaction objects; CE tables are designed to deliver additional information associated with the partner functions delivered with the transaction objects. This diagram shows some of the CE tables that are logically associated with the BUPA object.

CRM DOE DOE-CBAPIWrappers

Web Services

44

The CE tables conform to a standard layout. Each table effectively provides a container for storing name-value pairs, along with additional metadata associated with the item. This metadata includes data typing information, along with context, which allows data users to associate the rows with the relevant parent BUPA instance. An important thing to note is the presence of the two fields PARTNER and OBJECT_ID. These fields contain back-end keys and are used to correlate the CE table rows with other rows in the object. This functionality is particularly important when the CE rows are logically associated with child rows (for example, with child contacts or child items), rather than with the object header row.

The following tables show simplified examples of this. The first set of tables shows how to use CE_BUPA_HEADER to extend the main partner table and supply two additional fields: Z_LANGUAGE and Z_TIMEZONE. The main things to note are:

• Child rows in CE_BUPA_HEADER are correlated to the owning parent row using the back-end key field PARTNER.• The value of the field is stored in the FIELD_VALUE column.• The technical field label is supplied in FIELD_NAME, but the localized name of the field is in FIELD_TEXT.• Field datatypes are in DATA_TYPE, and additional metadata is in DECIMALS and KEY_LENGTH. (Not shown)• The PSYNCKEY can also be used as a correlation key. Its primary purpose, however, is to enforce ESDMA referential

integrity: all child objects (and CE tables are all technically child objects) require a PSYNCKEY to correlate to the parent (owning) row in the header table.

• Each row has the usual SYNCKEY to uniquely identify the row.• There is no use for the OBJECT_ID field, because we have enough information with the PARTNER field and/or the

PSYNCKEY field to tie this row to the partner object.

45

The next set of tables shows that we can supply additional fields into the child CONTACTS table. The main things to note here are:

• Two back-end key fields are needed to correlate a particular row in CE_BUPA_CONTACTS with the contact row in BUPA_CONTACTS: the PARTNER field (mapped to PARTNER in the BUPA_CONTACTS) and OBJECT_ID (mapped to CONTACT in the BUPA_CONTACTS table). We want to correlate rows in CE_BUPA_CONTACTS with a single owning row in BUPA_CONTACTS, not the BUPA_HEADER table.

• The other fields are used in the same way as for the main partner CE table. The PSYNCKEY is a correlation key to the row in BUPA_HEADER; it is not the “owning” row in BUPA_CONTACTS.

In general, all CE tables must supply:

• A SYNCKEY and a PSYNCKEY.• For BUPA-related CE tables, a PARTNER field to correlate to the back-end PARTNER ID.• For transaction-related CE tables, this field becomes the OBJECT_GUID field, which is used to correlate to the

transaction GUID.• An OBJECT_ID field that is used to supply additional back-end key field values.• Field name and value.• Datatype and additional metadata.

PopulatingCETablesAdditional code must be written in the CRM system to get data into CE tables. This code is executed in the context

of BADIs — extension or add-in code that is invoked when the BAPI wrappers that populate the ESDMA data entities are called.

Each object in the ESDMA (for example, a partner or lead) has a set of BAPI wrappers that are used either to push data from CRM to DOE or support create, update and delete operations from DOE to CRM. These BAPI wrappers allow the CRM system to mediate read and update, create and delete activities against the underlying data entities in the CRM system. Using the Advanced Business Application Programming language (ABAP) workbench, you can define BADIs that allow extensions to these BAPIs. These BADIs must implement a well-defined interface, which allows the BADI implementation to access and update data objects used during the relevant BAPI operation. The method signature includes all the data entities relevant to the particular object being updated. In the case of the partner object, this includes the partner header rows, along with the contacts tables, notes table and the CE tables.

46

This graphic shows the parameters associated with the interface that is used to implement the BADI used in the GETDETAIL extension point for the BUPA partner.

This ABAP code segment illustrates such an extension implementation. The code accesses supplied parameters (for example, ET_BUPA_HEADER_DETAILS) and ultimately inserts rows into the CE_BUPA_HEADER CE table.

method IF_EX_CRM_BUPA_MOB_SMARTPHONE~CRM_BADI_BUPA_MOBILE_GETDETAIL. Data: ls_bupa_header_details TYPE crms_bupa_mob_bpheader, ls_address TYPE bapibus1006_address, lt_bupa_header_details TYPE STANDARD TABLE OF crms_bupa_mob_bpheader, ls_ce_bupa_hdr TYPE CRMS_MOBILE_CUST_ENHANCE, lt_ce_bupa_hdr TYPE STANDARD TABLE OF CRMS_MOBILE_CUST_ENHANCE.

lt_bupa_header_details[] = et_bupa_header_details[]. LOOP AT lt_bupa_header_details INTO ls_bupa_header_details. CALL FUNCTION ‘BUPA_ADDRESS_READ_DETAIL’ EXPORTING IV_PARTNER = ls_bupa_header_details-partner IV_XADDRESS = ‘X’ IMPORTING ES_ADDRESS = ls_address EXCEPTIONS NO_PARTNER_SPECIFIED = 1 NO_VALID_RECORD_FOUND = 2 OTHERS = 3 . IF SY-SUBRC <> 0.* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF.

47

ls_ce_bupa_hdr-PARTNER = ls_bupa_header_details-partner. ls_ce_bupa_hdr-FIELD_NAME = ‘ZTIME_ZONE’. ls_ce_bupa_hdr-FIELD_TEXT = ‘Address time zone’. ls_ce_bupa_hdr-DATA_TYPE = ‘CHAR’. ls_ce_bupa_hdr-DATA_LENGTH = ‘6’. ls_ce_bupa_hdr-DECIMALS = ‘0’. ls_ce_bupa_hdr-FIELD_VALUE = ls_address-TIME_ZONE.

APPEND ls_ce_bupa_hdr to lt_ce_bupa_hdr. clear ls_ce_bupa_hdr.

ls_ce_bupa_hdr-PARTNER = ls_bupa_header_details-partner. ls_ce_bupa_hdr-FIELD_NAME = ‘Z_LANGUAGE’. ls_ce_bupa_hdr-FIELD_TEXT = ‘Language Key’. ls_ce_bupa_hdr-DATA_TYPE = ‘CHAR’. ls_ce_bupa_hdr-DATA_LENGTH = ‘2’. ls_ce_bupa_hdr-DECIMALS = ‘0’. ls_ce_bupa_hdr-FIELD_VALUE = ls_address-LANGUISO.

APPEND ls_ce_bupa_hdr to lt_ce_bupa_hdr.

CLEAR ls_ce_bupa_hdr.

ENDLOOP. CE_BUPA_HEADER[] = lt_ce_bupa_hdr[].

endmethod.

Some things to note:

• CE data cannot be created automatically. You must write ABAP code to populate the fields of the table.• Field names in the CE table must be manufactured. In this code snippet, the field names ZTIME_ZONE and Z_

LANGUAGE are used; however, these names are arbitrary.• Content inserted into the FIELD_VALUE field is determined by the ABAP code. In this case, the content comes

from the object in the CRM system that corresponds to the current BUPA instance. But there is no requirement for this. The BADI implementation must use CRM APIs to extract relevant CRM data. In this case, the API called is BUPA_ADDRESS_READ_DETAIL. CRM functional experts must ensure that BADI code is written correctly and calls the appropriate APIs.

• For device-initiated updates to be pushed back into CRM, you must write BADIs that extend the Change/Create BAPI wrappers. Without these, changes to CE table content are not pushed back into the CRM system: They simply remain in the Consolidated Data Store (CDS) on the DOE.

There is a general issue when handling CE table uploads from a device with Create/Change BAPI Wrappers. If a device is creating a new CE field, the device must supply a back-end key in the PARTNER (or OBJECT_GUID) field and, in some cases, in the OBJECT_ID field. If the CE fields are to be associated with an existing object, the device can obtain the back-end key value directly and set it in the CE row in the CE table. However, if the device is creating a new parent object that is to be associated with the CE fields, then the device will not have back-end key fields available.

Assume we want to create a new contact for a partner. This means creating a new contact child row in MAS_PARTNER_BUPA_HEADER_DETAILS. We also want to insert new CE rows in MAS_PARTNER_CE_BUPA_CONTACTS for the CE fields we want to associate with the new contact. This requires inserting data into both the PARTNER and OBJECT_ID fields in the CE row. We know the PARTNER value but not the OBJECT_ID value, which comes from the CONTACT back-end key when the contact is created. The BADI code that processes the uploaded data must associate the supplied CE rows with the back-end keys generated during the Change BAPI Wrapper call. To do this in a generic fashion, the device must supply temporary back-end key values that the BADI enhancement translates to actual back-end keys. Such keys must be defined unambiguously, and both the device and BADI enhancements must be written and tested.

48

To achieve this for nonheader CE field enhancements requires some additional design work, significant coding in the BADI enhancement layer and extensive testing. The CE field enhancement is supported onlyfor header rows. See the summary table for details of which tables are supported.

When Create BAPI Wrapper is called (creating a new top-level object), which then calls the BADI enhancement, the client does not need to supply a PARTNER (or OBJECT_GUID) value, because the Create Wrapper handles only single instances of the object. Thus, all child CE rows are automatically assumed to be associated with the single parent object, and the back-end PARTNER (or GUID) field can be filled in easily during the Create BADI extension call. When Change BAPI Wrappers is called, the device knows the PARTNER (or GUID) back-end key and can ensure that supplied CE rows are created with these field values populated.

SupportedTablesThis table shows all CE tables defined in the ESDMA and which tables are supported for customization.

TABLE NOTES

PARTNER

CE_BUPA_HEADER

CE_BUPA_CONTACTS Not supported

CE_BUPA_ROLE Not supported

CE_BUPA_SALESAREA Not supported

CE_BUPA_EMPLOYEE Not supported

ACTIVITY

CE_ET_ACTIVITY_H

CE_ET_ACTIVITY_PARTNER Not supported

CE_ET_ACTIVITY_NOTES Not supported

LEAD

CE_ET_HEADER

CE_ET_PARTNER Not supported

CE_ET_NOTES Not supported

CE_ET_ITEM Not supported

OPPORTUNITY

CE_ET_OPPT_HEADER

CE_ET_OPPT_PARTNER Not supported

CE_ET_OPPT_NOTE Not supported

CE_ET_OPPT_ITEM Not supported

SERVICEORDER

CE_ET_HEADER

CE_ET_PARTNER Not supported

CE_ET_NOTE Not supported

CE_ET_ITEMS Not supported

SALESORDER

CE_ET_HEADER

CE_ET_PARTNER Not supported

CE_ET_NOTE Not supported

CE_ET_ITEMS Not supported

49

BAPIWrapperChangesIt will be necessary to modify BAPI wrappers as follows:

GETLISTNot required. (These methods are already in the BAPI wrapper; developers don’t need to change anything in this method.)

GETDETAILAdd BADI logic to insert CE field data as appropriate to ensure that CE field data is downloaded to the device from

the CRM.

CREATEAdd BADI logic to push device-supplied CE field data into the CRM.

CHANGEAdd BADI logic to ensure that changed CE field data supplied by the device is updated in the CRM.

DELETERequired only if deleting the instance requires some action based on the CE field data.

CETableSemanticsWhen populating CE tables from the SAP back end, following certain conventions is important. These conventions

determine the allowed values for the columns in the CE tables. The clients support these values:

DATA_TYPE DATA_LENGTH DECIMALS NOTES

CHAR N Unused Character; N indicates number of characters

INT Unused Unused Signed integer (equivalent to long in C#)

BOOL Unused Unused Boolean; FIELD_VALUE contains X for true, blank otherwise

DATS Unused Unused SAP-style date representation (14 digit date format)

DEC N M Decimal; N indicates digits before decimal point; M those after

NUMC N Unused Number;N indicates number of digits

In addition, the client supports values for DATA_TYPE, which consist of four-digit string values in the form TTSX, where TT represents a base type, S a subtype and X additional attributes associated with the type. This table lists the types and allowed values for subtype.

TYPETT MEANING SUBTYPES MEANING

11 Integer 012

NormalLOVLOV + user input

12 Numeric None

13 Decimal None

14 Date None

15 Char None

16 Bool 01

NormalLOV

17 Time None

18 DateTime None

50

The attribute value X takes these values (with meanings):

ATTRIBUTE X MEANING

0 Updatable

1 Read-only

Time, Date and DateTime are all stored as 14-character numeric strings of the form YYYYMMDDHHMMSS. For Time, the YYYYMMDD characters are ignored (and ideally should be 0s); for Date, the trailing HHMMSS characters are ignored (and ideally should be 0s). Examples of acceptable values are (with meaning):

VALUE MEANING

1500 Normal character string

1501 Read-only character string

1700 Time

1610 LOV for Boolean

Note that the values INT, CHAR, NUMC, DEC, BOOL and DATS are equivalent to the SSTX numeric data types:

DATA_TYPE EqUIVALENTNUMERICFORMAT

INT 1100

DEC 1300

NUMC 1200

CHAR 1500

DATS 1800

BOOL 1600

LOV means List of Values. For types with the subtype LOV, the actual values that can be inserted into the FIELD_VALUE column are constrained. For example, there may be a CE field ZGENDER that has constrained values M and F. The UI would be expected to present the user with a drop-down list, allowing the user to choose from one of the two available values. The list of constrained values is supplied in a separate table WSAP_EXTENSION, which is a child table of the MAS_CUSTOMIZATION data object. The list of LOV values that is supplied in this table comes (logically) as a set of name-value pairs: the “name” matches the value that is acceptable in the FIELD_VALUE column of the actual CE table; the “value” is what is presented to the user in the drop-down list. Referring back to the ZGENDER example, while M and F are allowed values in the CE table, the user would like to see Male and Female.

The format of the WSAP_EXTENSION table that supports this is:

SYNCKEY_MMW PSYNCKEY ASSSIGNMENT COUNTER ITEM_KEY OBJECT_GUID VALUE

Synckey, filled in by system

Correlation key to parent

Either blank or the string DF to indicate default.

Numeric value indicating order in LOV.

Acceptable CE FIELD_VALUE

CE Field Name Display value

51

The next table, based on the ZGENDER example, illustrates this.

SYNCKEY_MMW PSYNCKEY ASSSIGNMENT COUNTER ITEM_KEY OBJECT_GUID VALUE

… … DF 1 M ZGENDER Male

… … 2 F ZGENDER Female

In this example, the base CE Field DATA_TYPE would be 1510 – Character LOV. Another example, using days of week, could be:

SYNCKEY_MMW PSYNCKEY ASSSIGNMENT COUNTER ITEM_KEY OBJECT_GUID VALUE

… … 1 Su ZWEEKDAYS Sunday

… … DF 2 M ZWEEKDAYS Monday

… … 3 T ZWEEKDAYS Tuesday

… … 4 W ZWEEKDAYS Wednesday

… … 5 Th ZWEEKDAYS Thursday

… … 6 Fr ZWEEKDAYS Friday

… … 7 Sa ZWEEKDAYS Saturday

RestrictionIt is assumed that identical CE field metadata is supplied for each object instance. For example, for BUPA instances,

there must be identical field definitions for each instance (although the field values will differ). For example, if Z_TIMEZONE and Z_LANGUAGE fields are defined for BUPA instances, these fields must exist across all BUPA instances.

MAS_PARTNER_CE_BUPA_HEADERCE fields are defined unambiguously and documented. For every row in MAS_PARTNER_ET_BUPA_HEADER_DETAILS

and for every defined CE field, there is a row in MAS_PARTNER_CE_BUPA_HEADER.

FIELDNAME COMMENTS

SYNCKEY_MMW Synckey (system generated)

PSYNCKEY Correlation key to SYNCKEY_MMW in MAS_PARTNER_ET_BUPA_HEADER_DETAILS

PARTNER BE Key PARTNER from MAS_PARTNER_ET_BUPA_HEADER_DETAILS

OBJECT_ID Unused

KEY_LENGTH Unused

FIELD_NAME Technical field name

FIELD_TEXT Localized (human-readable) field name

FIELD_VALUE Field content

DATA_TYPE A standard datatype

DATA_LENGTH As appropriate for datatype

DECIMALS As appropriate for datatype

GENERAL_FLAG Unused

52

MAS_ACTIVITY_CE_ET_ACTIVITY_HCE fields are defined unambiguously and documented. For every row in MAS_ACTIVITY_ET_HEADER_H and for every

defined CE field, there is a row in MAS_ACTIVITY_CE_ET_ACTIVITY_H.

FIELDNAME COMMENTS

SYNCKEY_MMW Synckey (system generated)

PSYNCKEY Correlation key to SYNCKEY_MMW in MAS_ACTIVITY_ET_HEADER_H

OBJECT_GUID BE Key OBJECT_GUID from MAS_ACTIVITY _ET_HEADER_H

OBJECT_ID BE Key OBJECT_ID from MAS_ACTIVITY _ET_HEADER_H

KEY_LENGTH Unused

FIELD_NAME Technical field name

FIELD_TEXT Localized (human-readable) field name

FIELD_VALUE Field content

DATA_TYPE A standard datatype

DATA_LENGTH As appropriate for datatype

DECIMALS As appropriate for datatype

GENERAL_FLAG Unused

MAS_LEAD_CE_ET_HEADERCE fields are defined unambiguously and documented. For every row in MAS_LEAD_ET_HEADER and for every

defined CE field, there is a row in MAS_LEAD_CE_ET_HEADER.

FIELDNAME COMMENTS

SYNCKEY_MMW Synckey (system generated)

PSYNCKEY Correlation key to SYNCKEY_MMW in MAS_LEAD_ET_HEADER

OBJECT_GUID BE Key OBJECT_GUID from MAS_LEAD_ET_HEADER

OBJECT_ID BE Key OBJECT_ID from MAS_LEAD_ET_HEADER

KEY_LENGTH Unused

FIELD_NAME Technical field name

FIELD_TEXT Localized (human-readable) field name

FIELD_VALUE Field content

DATA_TYPE A standard datatype

DATA_LENGTH As appropriate for datatype

DECIMALS As appropriate for datatype

GENERAL_FLAG Unused

53

MAS_OPPORTUNITY_CE_ET_OPPT_HEADERCE fields are defined unambiguously and documented. For every row in MAS_OPPORTUNITY_IT_OPPT_HEADER and

for every defined CE field, there is a row in MAS_OPPORTUNITY_CE_ET_OPPT_HEADER.

FIELDNAME COMMENTS

SYNCKEY_MMW Synckey (system generated)

PSYNCKEY Correlation key to SYNCKEY_MMW in MAS_OPPORTUNITY_IT_OPPT_HEADER

OBJECT_GUID BE Key OBJECT_GUID from MAS_OPPORTUNITY _IT_OPPT_HEADER

OBJECT_ID BE Key OBJECT_ID from MAS_OPPORTUNITY _IT_OPPT_HEADER

KEY_LENGTH Unused

FIELD_NAME Technical field name

FIELD_TEXT Localized (human-readable) field name

FIELD_VALUE Field content

DATA_TYPE A standard datatype

DATA_LENGTH As appropriate for datatype

DECIMALS As appropriate for datatype

GENERAL_FLAG Unused

CRMApplicationontheDeviceFor the CE tables to be useful, the CRM application running on the device must be able to properly use the data

pushed through the CE tables. The application logic must correctly interpret the CE table fields and correctly handle the relationships between data rows in the CE tables and the main object header fields. This means that populating the CE tables in the BADI enhancement ABAP code must conform to the table definitions as specified previously.

The application processes CE data like this:

MAS_PARTNER_CE_BUPA_HEADER

Display (Inspect)When displaying details for a particular partner, the application’s ABO layer queries this CE table and retrieves rows

for which the PARTNER field matches the partner’s PARTNER field content. Each retrieved row represents a field to appear in the UI. Field metadata determines how to interpret the field content. For Windows Mobile, a standard Resco row template renders the field content. For iPhone, metadata-driven UI logic renders each retrieved field.

Update (Act)The application ABO layer retrieves details about the available CE fields and uses standard template logic to display

the correct UI.

Create (Act)On partner create, the application cannot retrieve CE field data associated with the partner instance, because this

information will not yet have been pushed to the device. The CE table cannot be queried to retrieve the available CE field metadata. The only way the application candynamicallyretrieve this information (without it being supplied either in source code or through configuration files) is for the application to retrieve the necessary metadata from an existing partner instance. Effectively, an existing partner is used as a template to determine the CE fields that are available for a new partner.

The CE field metadata retrieved from an existing partner drives the UI.

If there are no existing partners on the device, the application cannot determine what CE fields exist and so cannot render the correct UI. Once the partner is created and synced to the back end, the necessary CE field data is pushed back to the device (in the create/update/delete confirmation message), but this requires a two-step process to insert CE field data on a newly created partner.

54

MAS_ACTIVITY_CE_ACTIVITY_H

Display (Inspect)When displaying details for a particular activity, the application’s ABO layer queries this CE table and retrieves rows

for which the OBJECT_GUID field matches the activity’s OBJECT_GUID field content. Each retrieved row represents a field to appear in the UI. Field metadata determines how to interpret the field content. For Windows Mobile, a standard Resco row template renders the field content.

Update (Act)The application ABO layer retrieves details about the available CE fields and uses standard template logic to display

the correct UI.

Create (Act)On activity create, the application cannot retrieve CE field data associated with the partner instance, because this

information will not yet have been pushed to the device. The CE table cannot be queried to retrieve the available CE field metadata. The only way the application candynamicallyretrieve this information (without it being supplied either in source code or through configuration files) is for the application to retrieve the necessary metadata from an existing activity instance. Effectively, anexisting activity is used as a template to determine the CE fields that are available for a new activity.

The CE field metadata retrieved from an existing activity drives the UI.

If there are no existing activities on the device, the application cannot determine what CE fields exist and so cannot render the correct UI. Once the activity is created and synced to the back end, the necessary CE field data is pushed back to the device (in the create/update/delete confirmation message), but this requires a two-step process in inserting CE field data on a newly created activity.

MAS_LEAD_CE_ET_HEADER,MAS_OPPORTUNITY_CE_OPPT_H,etc.These are almost identical to MAS_ACTIVITY_CE_ACTIVITY_H support.

RequiredStepsIn general, to develop a solution that uses CE tables, these steps are required:

1. Decide for each object (partner, activity and so on) what additional fields or attributes from the back-end CRM tables are to be made available on the device.

2. Define the required mappings from these attributes to CE tables and fields that will deliver the attributes to the device. Decide which CE tables, field names and associated metadata are to be used.

3. Write BADI enhancements, conforming to CE table semantics. Determine which ABAP APIs are required to access the back-end CRM attributes:a. GetDetail BAPI wrapper enhancement that extracts data into the CE tableb. Change BAPI wrapper enhancement that allows device-initiated operations to push changed data back into

CRMc. Create BAPI wrapper enhancement that allows the device to insert new instancesd. Delete BAPI wrapper enhancement, supporting deletes from the device. Generally, this wrapper is needed

only under exceptional circumstances (for example, if deleting an object instance requires using the CE table data to perform some additional cleanup).

55

Development/qATestStrategyTest the CE table enhancement feature with these use cases.

Usecase1:AccountsThis use case works with the Account partner objects and associated CE tables.

Setup1. Select the Timezone and Language fields associated with the Partner instance for delivery to the device through

DOE.2. Deliver through CE_BUPA_HEADER table.3. Use CE field names ZTIME_ZONE (with English language text Timezone) and Z_LANGUAGE (with English

language text Language).4. Create BADI enhancements for the GetDetail and Change and Create BAPI Wrappers used for the Partner object.

Use transaction se80 to launch the ABAP editor.

Choose Package from the drop-down list, and select CRM_SALES_ANALYTIC_SMARTPHONE.

Under Enhancements->Enhancement Spots, double-click CRM_MOBILE_SMARTPHONE.

56

Under BADI Definitions, open CRM_BUPA_MOB_SMARTPHONE, right-click Implementations and choose Create BADI Implementation.

Right-click in the table showing existing implementations, and choose Create.

Enter the name of the enhancement implementation, enter short text and select OK.

57

Enter $TMP as the package name, and click Local Object.

Select the Create Enhancement Implementation and click OK.

Enter details for the BADI implementation and class, and add a description.

58

Click Local Object.

On the Enhancement Implementation screen, expand the BADI implementation you just created and double-click Implementing Class.

Double-click the GetDetail method.

59

Select Yes when prompted to create the implementation.

Fill in the ABAP code necessary to implement the method (click the pencil icon to make the pane editable).

60

Save and Activate the object.

Ensure that the initial download is triggered.

Teststrategy1. Set or check the timezone and language fields for the selected Account partner in the Web UI.2. Ensure that the timezone and language fields are visible for this partner in the CRM device application.3. Update timezone and language values on the device for this account.4. Verify that the new values are pushed back to the CRM by checking the Web UI.5. Create a new account on the device, setting the language and timezone values.6. Verify that the values are pushed to the CRM and visible in the Web UI.

Usecase2:Activities

Setup1. Define some arbitrary fields ZFIELD1 (English text Field1) and ZFIELD2 (English text Field2).2. Create a simple GetDetail BADI extension for the Activity object, which creates fixed values for the predefined

fields defined, rather than using CRM APIs to extract actual CRM fields.3. No Change or Create BAPI Wrapper enhancements are required.

61

Teststrategy1. After defining the BADIs and triggering initial download to the CDS, use the DOE ABAP workbench to check the

contents of the CDS table CE_ACTIVITY_H and ensure that it contains rows for all the new fields (ZFIELD1 and ZFIELD2) for each activity.

2. Check that the fields are pushed to the device and are visible against the Activity objects.3. Update one of the fields on the device.4. Check that the new field values are pushed back to CDS in DOE.5. Create a new activity, and set values for the new fields.6. Check that the field values are pushed back to the CDS with the newly created activity.

To check the content of the CDS:

In DOE, launch the Data Orchestration Workbench.

Expand the MAS_SMARTPHONE, 1.4 of SAP entry.

62

Expand to the MAS_ACTIVITY object under Data Object Category -> Standard -> Data Objects. Right-click and select View Metadata.

63

Double-click the Generated Object associated with the CE_ET_ACTIVITY_H entry.

Click the Contents icon.

64

Click the Execute icon.

This shows the CDS contents that are associated with the activity CE header table.

65

impLemeNtiNg CuStOm exteNSiONSThis section discusses customization options for tailoring the Mobile Sales application to support specific business

requirements. The source code is structured into Visual Studio 2008 projects:

• CRMDataEntities – contains compiled MBO code autogenerated from ESDMA.• CRMUtils – contains some support utility classes.• CRMBusinessObjects – contains the ABO (application business objects) layer.• SybaseCRMPro – the UI project for Professional.• SybaseCRMStd – the UI Project for Standard.• SybaseCRMControls – the project for UI controls.

There are additional projects for CAB generation, as well as projects that cover menu extensions used to enhance native PIM applications (Contacts/Calendar/Mail).

CRMDataEntitiesThis project encapsulates the generated files produced by converting the ESDMA bundle to C# classes. The only

reason to change this project is if a new code generator is available, producing different code from the same ESDMA, or if the ESDMA itself changes.

The build result from this project is a single cross-platform DLL: CRMDataEntities.dll.

CRMUtilsThis project contains some useful utility classes. It is likely that no changes here will be necessary, unless additional

support classes are required or if bugs are discovered in these classes.

CRMBusinessObjectsThis project contains the main ABO layer and mediates all access to the CRMDataEntities layer: the UI layer has no

exposure at all to the classes in CRMDataEntities.dll.

The main SAP objects — Accounts, Contacts, Leads, Opportunities and so on — are reflected directly at this level. The classes that represent these entities are structured using a core class (for example, AccountCore) that contains base functionality and a top-level class (for example, Account) that mostly extends the base class. The top-level class is presented using partial classes, because it is assumed that end users will modify the code in the top-level partial class, overriding functionality inherited from the core class.

SybaseCRMPro/SybaseCRMStdThese UI layer projects access the CRMBusinessObjects layer to obtain and work with SAP-related entities. The code

in these projects uses Resco XML templates to render the UI. These templates are included directly in the projects (Standard and Professional devices use different sets). Sybase anticipates that most UI-related changes can be carried out by changing only the XML templates.

Code changes to these projects is required only if logic changes are needed to render the UI. This might happen, for example, if wizards are altered to allow the creation of new entities, or if new device interaction models are required.

Menus are defined in the code, rather than in XML or configuration files, so changes to the menu structure will require changes to the project itself.

66

SybaseCRMControlsCertain controls are defined in this project. If changes to control behavior (for example, specialized menu bars) are

required, those changes will be made in this project.

CustomizingConfigurationFilesforWindowsMobileWindows Mobile uses XML files to control how screens are rendered. These XML files can be changed, if necessary.

Generally, partners carry out such changes by delivering a solution to an end user; these changes will be carried out before deployment to the devices. Images and language resource bundles are also shipped with the device.

Partners can make significant changes to an application’s look and feel by modifying these XML, image and resource bundles, along with the templates used to hold initial copies of the application settings.

XML templatesAll UI screens are rendered with an XML template that controls how fields are positioned on the screen. These XML

templates can be modified. Changes might include:

• Rearranging or hiding fields • Changing field size• Changing fonts• Altering colors

The XML files are located in the …\Templates\UI\Pro (or Std) directories.

Partners must understand the structure of the XML files, but this should not be a significant challenge. Resco controls use the XML files, and documentation that describes how the XML file is structured is available.

ImagesAll images used by the application are located in the …\Resources\Images directory. Partners can replace

images with alternative images. The file name must remain the same, but the image content can be changed.

Language resource bundlesThese bundles are located in the language directories (for example, …\de). Partners can develop new resource

bundles for new languages.

Configuration fileThis file is located in the …\Templates directory. At application start-up, a copy is made into the …\Data

directory. Partners may choose to ship a default copy with changes that are suited to their requirements.

ApplicationEnhancementApplication enhancement means that partners make changes to the application source code. These changes may

include ABO extensions, UI-level enhancements, and/or ABO class changes.

ABO extensionsIf changes to the ABO layer are required, partners should first write extension classes that enhance the standard

ABO components. These classes can then override or extend functionality exposed in the ABO classes. The MBO and ABO layers remain untouched. The extension classes form an additional layer that holds all the required changes. The existing UI code (with the XML templates) then uses the extended ABO classes.

UI-level enhancementIf changes to the UI are required that are not deliverable using changes to the XML templates, then partners must

make code changes to the UI layer to enable the required UI behavior. Ideally, all UI changes should be encapsulated in changes to the XML templates, and it is expected that changes to the UI code will be rare.

67

ABO class changesPartners can modify the ABO layer directly; however, this is required only if it is impossible to implement the

required changes using one of the other approaches.

ESDMAEnhancementsWhen enhancing the data entities, partners must decide if the changes required can be accommodated within CE

tables or whether the changes require an enhanced ESDMA. An enhanced ESDMA requires these steps:

1. A new set of MBOs will need to be generated.2. Either ABO partial classes are written or existing ones modified to expose or handle the changed data entities as

exposed in the MBOs.3. Possible changes made to ABO classes.4. XML template changes made as appropriate.5. UI code changes only if absolutely necessary.

www.sybase.com

Sybase, Inc. Worldwide HeadquartersOne Sybase DriveDublin, CA 94568-7902U.S.A1 800 8 sybase Copyright © 2011 Sybase, Inc. All rights reserved. Unpublished rights reserved under U.S. copyright laws. Sybase, the

Sybase logo and Afaria are trademarks of Sybase, Inc. or its subsidiaries. ® indicates registration in the United States of America. SAP, the SAP logo and NetWeaver are the trademarks or registered trademarks of SAP AG in Germany and in several other countries. All other trademarks are the property of their respective owners. 03/11

iPhone is a registered trademark of Apple Inc.