Sunteți pe pagina 1din 67

Understanding the Personify API

January 2009

TMA Resources 1919 Gallows Road Suite 400 Vienna, VA 22182 www.tmaresources.com

Copyright Information
2009 TMA Resources, Inc. All rights reserved. Produced in the United States of America. All material contained in this documentation is the confidential and proprietary property of TMA Resources, Inc. No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form by any means, electronic or otherwise, without the written permission of the publisher, TMA Resources, Inc. All trademarks, service marks, and trade names referenced in this material are the property of their respective owners. TIMSS and Personify are registered trademarks of TMA Resources, Inc. Microsoft, Windows, SQL Server, .NET, and Notepad are registered trademarks of Microsoft Corporation. Group 1, CODE-1, and Universal Coder are registered trademarks of Group 1 Software, Inc. Crystal Reports is a registered trademark of Business Objects SA. EXPOCAD is a registered trademark of Applied Computer Technology, Inc. NetAdvantage is a registered trademark of Infragistics, Inc. Firefox is a registered trademark of Mozilla Corporation. Payflow Pro is a registered trademark of PayPal. CyberSource is a registered trademark of CyberSource Corporation. Intel is a registered trademark of Intel Corporation. Wells Fargo is a registered trademark of Wells Fargo. Lyris ListManager is a registered trademark of Lyris Technologies, Inc. BusinessObjects and WebIntelligence are a registered trademark of Business Objects SA.

Warranties & Disclaimers


The information contained in this publication may be out-of-date or include omissions, inaccuracies or other errors. Except where expressly provided otherwise in an agreement between you and TMA Resources, all information in this publication is provided as is without warranty of any kind. TMA Resources hereby disclaims all warranties with respect to this information, whether express or implied, including the implied warranties of merchantability and fitness for a particular purpose. In no event shall TMA Resources be liable for any direct, indirect, incidental, special or consequential damages, or damages for loss of profits, revenue, data or use, incurred by you or any third party, whether in an action in contract or tort, arising from your access to, or use of this publication. TMA Resources reserves the right to make changes or updates to this documentation at any time without notice.

Table of Contents
Personify API Overview...................................................................................... 1
Goals for the API ........................................................................................................ 1 Library Hierarchy ........................................................................................................ 2

The Core Layer.................................................................................................... 3


Application .......................................................................................................... 3 BusinessObjectCollection ................................................................................... 3 BusinessObject ................................................................................................... 3 Schema and PropertyInfo ................................................................................... 4 Functionality Implemented in the Core Layer ............................................................. 4 Authentication ..................................................................................................... 4 Authorization ....................................................................................................... 5 Caching ............................................................................................................... 5 Communicating with the Data Access Layer ...................................................... 7 Instantiating a Collection ..................................................................................... 8 Filling a Collection with Data ............................................................................... 8 Modifying Data in a Collection .......................................................................... 10 Sorting Collections ............................................................................................ 14 Finding an Object in a Collection ...................................................................... 14 Overriding Context Values ................................................................................ 14 Specifying Collection Filters .............................................................................. 14 Complex Search Queries .................................................................................. 15

The Generated Layer ........................................................................................ 16


API Model Files......................................................................................................... 17 The Code Generation Process ......................................................................... 17 Code Generation Tools..................................................................................... 17 Working with the Code Generator Interface...................................................... 17

Elements of the API Model............................................................................... 19


Personify................................................................................................................... 19 ObjectModel.............................................................................................................. 19 DataTypes ................................................................................................................ 19 DataType .................................................................................................................. 19 Namespaces............................................................................................................. 20 Namespace............................................................................................................... 20 Collection .................................................................................................................. 20 Item........................................................................................................................... 21 Properties ................................................................................................................. 22 Property .................................................................................................................... 22 CapitalizationFacet ................................................................................................... 27 StringPaddingFacet .................................................................................................. 28 RegexValidationFacet............................................................................................... 28 DateFacet ................................................................................................................. 28 Methods .................................................................................................................... 28 Method...................................................................................................................... 28 Parameters ............................................................................................................... 29

2009 TMA Resources, Inc.

Proprietary & Confidential

The Interfaces Library ...................................................................................... 30


Collection Interface ................................................................................................... 30 Item Interface............................................................................................................ 30

The Base Layer ................................................................................................. 32


Division of Database Tables ..................................................................................... 32 Common Functions/Properties of API Collections.................................................... 33 CreateNew and AddNew .................................................................................. 33 Fill ..................................................................................................................... 33 Accessing Dataset and DataRow Properties .................................................... 33 Programming Tasks.................................................................................................. 34 Existing Code Base........................................................................................... 34 Verifying the Code Generation Metadata.......................................................... 34 Value Properties ............................................................................................... 34 Code Properties ................................................................................................ 35 List Properties ................................................................................................... 35 Applying Default Values .................................................................................... 35 Ensuring Referential Integrity............................................................................ 35 Implementing Calculated Members .................................................................. 35 Providing Shortcut Methods and Properties ..................................................... 36

Understanding Validation Issues .................................................................... 37


A Validation Issue is a Class............................................................................. 37 Naming Standards for Validation Issues ........................................................... 37 Validation Issue Classes Are Not Generated Code .......................................... 37 Validation Issues Are Not Messages ................................................................ 38 Validation Issues Are Not Exceptions ............................................................... 38

Validation Issues During Runtime................................................................... 39


Setting Message ID Numbers ........................................................................... 39 Use of AutoResponses ..................................................................................... 39 Clearing Validation Issues ................................................................................ 39 Continue Processing or Exit.............................................................................. 39

Validation Issue Infrastructure ........................................................................ 41


Classes ..................................................................................................................... 41 AutoResponsesCollection ................................................................................. 41 IssueBase ......................................................................................................... 41 IssueEventArgs ................................................................................................. 43 IssueResponse ................................................................................................. 43 IssueResponsesCollection................................................................................ 44 IssuesCollection ................................................................................................ 44 IIssue ................................................................................................................ 46 IIssuesCollection ............................................................................................... 47 IssueSeverityEnum ........................................................................................... 49 StandardIssueResponseEnum ......................................................................... 49

Core Validation Issues ..................................................................................... 50


PropertyMissingIssue........................................................................................ 50 BusinessObjectPropertyMissingIssue............................................................... 50 InvalidPropertyValueIssue ................................................................................ 50

2009 TMA Resources, Inc.

Proprietary & Confidential

ii

YesNoIssue....................................................................................................... 50 DuplicateObjectIssue ........................................................................................ 50

Validation Issue Examples............................................................................... 51


OrderInfo Validation Issue Examples ....................................................................... 53 MeetingRegistrationIssue ................................................................................. 53 ProductOutofStockIssue ................................................................................... 53 InvalidDateRangeIssue ..................................................................................... 57 CustomerInfo Validation Issue Examples ................................................................. 58 AddressValidationIssue .................................................................................... 58 SegmentWithMembersDisabledIssue ............................................................... 59 SegmentChangeWithMembersIssue ................................................................ 59 UpdateSubCustomerStatusToReflectMasterCustomerStatusIssue ................. 59 MarkAddressAsBillToORShipToIssue .............................................................. 60 CreateMultipleLinksToPrimaryAddressIssue .................................................... 60 EmailExistAsPrimaryForAnotherCustomerIssue .............................................. 61 PrimaryEmployerAlreadyExistsIssue ................................................................ 61 PrimaryContactAlreadyExistsIssue ................................................................... 61 DuplicateCustomerMatchesFoundIssue ........................................................... 62

2009 TMA Resources, Inc.

Proprietary & Confidential

iii

Goals for the API

Personify API Overview


The Personify (TIMSS) API is a .NET framework class library that provides programmatic access to your Personify database. The library encapsulates all business logic related to managing the association data model. The API library is used for all access to Personify data from the Personify application, eBusiness, and customers who develop customized Personify applications. The TIMSS API supports customization of the data model and business rules at the code level through inheritance. The goal of this document is to give you an in-depth look at how Personify uses its APIs and API libraries.

Goals for the API


The primary design goals for the API are: Centralized Business Logic All of the logic needed to work with Personify is coded into API objects. This assists in user-interface development and gives you flexibility to create new interface. Shortening the Development Cycle Assists in shortening the time-to-market for development activities. Product Stability Reduces the efforts needed to stabilize the product. Encapsulation Reduces the complexity of the system by giving programmers a clear path to navigate through objects in the system. This minimizes the amount of information needed to make changes and reduces the number of steps needed to perform a task. Ease of Customization Allows our programmers to modify the base system to meet your business needs. Flexible Configuration Can be installed in a variety of network architectures. Personify can be load-balanced and/or can work against a clustered database. It can also be made accessible to clients on the same LAN, from remote offices, or over the internet.

2009 TMA Resources, Inc.

Proprietary & Confidential

Library Hierarchy

Library Hierarchy
To support development and customization, the API library is built in layers, providing increasing levels of specialization. In practice, the library is delivered as two distinct compiled binaries: TimssAPIBase.dll The core and generated code. TimssAPI.dll The base code. Currently, code for all subsystems is included in the binaries. This scheme must be modified to support proper packaging and deployment of the final product. Customer Generated Layer Base Layer Generated Layer Core Layer

The Core, Generated, and Base layers can only be modified by TMA Resources programmers (the Professional Services team can also not modify these layers). The Customer Generated Layer can be modified by TMA Resources customers by using the Database Designer in Personify. The Database Designer contains the definitions for the tables and columns added by the end user. For more information on the Database Designer see the Personify Studio Tools User Guide.

2009 TMA Resources, Inc.

Proprietary & Confidential

Library Hierarchy

The Core Layer


The Core Layer provides the infrastructure needed for an application to work with the Personify data model, as well as a set of base classes from which subsequent API layers derive. The Core Layer contains common Methods and Properties to control Retrieval, Validation, Saving, etc. The Core Layer contains a set of generic data access classes that are able to interact with the TimssDB database access library. The primary generic classes are: TimmsCollection This represents a bindable list of objects, equivalent to a table in a database. TimssObject This represents a single item from a Collection, equivalent ot a row from a table in the database. TimssRelationship This represents a parent/child relationship between two TimssCollection objects, equivalent to a foreign key constraint in the database. TimssDataObject This is a generic bindable component that contains one or more TimssCollection objects. The function of the TimssDataObject is to provide late-bound access to TimssObjects at runtime. TimssSystem This is a class that contains the methods needed to authenticate to a TIMSS database, activate remote server objects, provide design-time support, and encapsulate the reflection functionality needed for late-bound objects. The following sections provide a brief description of the primary classes in the Core API.

Application
The Application class is the primary class in the API. The Application class handles all communications with the data access layer, manages the individual API layers, and provides authentication, authorization, state management, and caching services. The class is implemented as a single instance, meaning there can only be one instance of an Application object for a given application domain (i.e., an instance of a Personify client application).

BusinessObjectCollection
The BusinsessObjectCollection class is the base class for all API Collections. A BusinessObjectCollection is analogous to a Table in a relational database. The BusinessObjectCollection class has properties and methods to manage fetching the appropriate data from the database, caching retrieved data, caching related data, reading table schema information, and inserting and deleting items from the collection.

BusinessObject
The BusinessObject class is the base class for all Item types in the API. A BusinessObject is analogous to a Row in a relational database. The BusinessObject class provides property access to the individual columns in the underlying row and standard business logic for

2009 TMA Resources, Inc.

Proprietary & Confidential

Functionality Implemented in the Core Layer

validating property values, generating appropriate SQL statements to update the row in the database, and navigating to related collections and items.

Schema and PropertyInfo


The Schema and PropertyInfo classes provide metadata about the BusinessObjectCollection and BusinessObject classes. Each BusinessObjectCollection/BusinessObject combination shares a Schema object. A schema object is a collection of PropertyInfo objects, which provide metadata for each of the BusinessObjects properties. There are three categories of properties: Value properties Correspond to columns in the BusinessObjects underlying data row. Value properties include types such as String, Boolean, DateTime, Integer, and Decimal. They are bound to a database column. Code properties Correspond to columns in the underlying data row and specify a Codes class that enumerates the valid values for that column. They are bound to a database column type of CODE_CODE. List properties Return other BusinessObjectCollections or singular BusinessObjects. List properties are the implementation of relationships between tables in the database. Transient properties Provides a means to reference calculated or derived information at runtime through a property statement. Transient properties are not stored in the database. They are based on business logic. Transient properties can be of a Value, Code, or List property. For example, the Customer object represents a row in the CUSTOMER table. It has a LastName property, which is a Value property that refers to the LAST_NAME column. This is also a JobFunctionCode property, which is a Code property that refers to the JOB_FUNCTION_CODE column. This verifies that valid values for this column are read from the APP_CODE table, where subsystem=CUS and type=JOB_FUNCTION. The Customer class also has a Demographics property, which returns a CustomerDemographics collection. This is a List property that defines the relationship between the CUSTOMER and CUS_DEMOGRAPHICS tables.

Functionality Implemented in the Core Layer


Authentication
Authentication is handled by the PersonifyPrincipal and PersonifyIdentity classes, which implement the System.Principal.IPrincipal and System.Security.Principal.IIdentity interfaces respectively. Authentication is initiated by a call to the Application.Connect() method. The Connect() method instantiates a new PersonifyPrincipal object. It passes the database name, UserId, and password on the constructor. The Validate() method of the PersonifyPrincipal object

2009 TMA Resources, Inc.

Proprietary & Confidential

Functionality Implemented in the Core Layer

performs the actual authentication. It selects the appropriate data from the SEC_USER and SEC_GROUP_MEMBER tables and instantiates the PersonifyIdentity object. If authentication is successful (i.e., a record is retrieved from the SEC_USER table), the IsAuthenticated flag in the PersonifyIdentity interface is set to TRUE. The IPrincipal interface requires a read-only property, Roles(), which is a string array listing the roles in which the particular user can participate. For the PersonifyPrincipal object, the ORG_ID, ORG_UNIT_ID, and USER_GROUP columns combine from SEC_GROUP_MEMBER to create the entries in the Roles() array. For example, a user who is a member of the Admin user group in the NSSWP organizations NSSWP org unit and is a member of the CALLCENTER group in the NSSWPs FNDTN org unit, has two entries in the Roles() array: NSSWP/NSSWP/ADMIN and NSSWP/FNDTN/CALLCENTER. The Connect method sets System.Threading.Thread.CurrentPrincipal to the newly created PersonifyPrincipal object.

Authorization
User Authorization
Every call to the data access layer is authorized by the application object. Authorization is implemented in the application objects AuthCheck() method. AuthCheck looks at the current threads identity object to ensure the IsAuthenticated flag is TRUE. It then uses the OrgId and OrgUnitId properties from the current context to find an entry in the current threads Principal.Roles() collection. If an entry is found, the request is authorized. As long as the user is a member of any group for the Organization/OrgUnit they wish to access, the request will pass.

Data Access Authorization


Every call to the data access layer requires an AccessToken object. The AccessToken contains the database name, user ID, and some encrypted data. It is created by the API.Core.Application object. The data access layer verifies the access token before processing the request and throws an InvalidAccessToken Exception if invalid. This mechanism is meant to ensure the data access layer only accepts calls from the Application object. It allows you to have a stateless data access layer that does not have to reauthenticate every request. The data access layer trusts the application object to handle authentication and authorization.

Caching
The API Core implements a variety of caching mechanisms to improve performance.

Type Cache
The Type Cache maintains a list of resolved API types (BusinessObjectCollections and BusinessObjects). It is implemented as a HashTable, keyed by the shortened API type name (the API Namespace and Class name, without the library prefix). As API types are resolved,

2009 TMA Resources, Inc.

Proprietary & Confidential

Functionality Implemented in the Core Layer

they are added to the Type Cache, improving the performance of the API by reducing the need to search through the various API layers to find the most derived object type. The cache exists for the life of the application and items are never automatically cleared from it, however, the cache does have a Clear() method to allow it to be reset programmatically.

Schema Cache
The Schema Cache maintains the SQL table schemas for each API collection. It is implemented as a Dataset that contains a DataTable for each referenced table. When a new collection is instantiated, it first looks for its table schema in the Schema Cache and if not found, the collection executes a SELECT * FROM table name WHERE 1=2 statement in order to receive an empty table definition from the database. It then stores these results in the Schema Cache. The cache exists for the life of the application and items are never automatically cleared from it, however, the cache does have a Clear() method to allow it to be reset programmatically. The table schema is fetched from the database at runtime, rather than simply relying on the schema information from generated code. This allows accessing customer columns on any table in the database without having to re-generate or re-compile the code.

Codes Cache
The Codes Cache stores data for classes that implement the ICode interface. These are lists containing name/value (or code/description) pairs and support enumeration and validation of code type properties. The cache is implemented as a HashTable, keyed by the individual codes GetHashKey() function. Each ICode class is responsible for implementing the appropriate GetHashkey() function that uniquely distinguishes its list from any other code list. The cache exists for the life of the application and items are never automatically cleared from it, however, the cache does have a Clear() method to allow it to be reset programmatically.

Application-Level Data Cache


The Application-Level Data Cache is a data set intended to hold table data that does not change for the life of a particular application. The intent is to tag individual API collection types as able to be cached at the application level, which informs collections to first look at the Application-Level Data Cache when filling.

Collection-Level Data Cache


Every API collection has a private member variable called _Dataset, of type Dataset. When the collection is a Top-Level collection (i.e., it has no ParentObject), the _Dataset member is instantiated as a new Dataset and a table is added to hold the collections data. Any descendent collections from the top-level collections set their _Dataset member to the TopLevel collections _Dataset and add their own data table to it if needed. For any API collection, all of the collections data, as well as the data for any child collection, is stored in a single dataset. The tables in the dataset are named using the SQL table name and properties derived from the same table share that table in the underlying dataset. For example, if you are given an order that has the same BillTo and ShipTo customer, a new OrderMasters collection is instantiated, which creates a new dataset and adds an

2009 TMA Resources, Inc.

Proprietary & Confidential

Functionality Implemented in the Core Layer

ORDER_MASTER table to hold the order master data. When the BillToCustomer is referenced, since no customer data has yet been retrieved, a select statement is executed to retrieve customer data from the database. This data is stored in the CUSTOMER table of the OrderMasters collections dataset. When the ShipToCustomer property is referenced, since the customer ID points to the same customer, no data is retrieved from the database. The ShipToCustomer object is pointed to the same underlying row as the BillToCustomer.

Communicating with the Data Access Layer


All communications with the data access layer are done via two methods in the Application object, GetData() and SaveData(). Both methods pass an AccessToken and RequestSet to the corresponding method in the Data Access layer.

The AccessToken is described in the Data Access Authorization section of this document. The RequestSet object is a collection of RequestItem objects. A RequestItem object is an object that implements the IRequestItem interface. It embodies a SQL statement. The following classes implement IRequestItem:
Class BaseRequest DeleteRequest InsertRequest NextIdRequest Description Base class for request items. Executes a DELETE statement. Executes an INSERT statement. Executes the AppNextNumber stored procedure to receive an auto numbered column value. Issues a SELECT COUNT(*) statement. Issues a SELECT statement. Executes a generic SQL statement. Executes a SELECT*FROM table name WHERE 1=2 to get an empty table schema. Used to check CONCURRENCY_ID column value.

RowCountRequest SelectRequest SimpleRequest TableSchemaRequest VersionCheckRequest

Since the data access methods accept a RequestSet object, multiple independent requests can be bundled together and sent to the data access layer as a batch. The data access layer executes each RequestItem in the RequestSet and records the results in a results dataset. For GetData() calls, the data access layer creates a table in the results dataset for each RequestItem. For SaveData() calls, the data access layer creates a table in the

2009 TMA Resources, Inc.

Proprietary & Confidential

Functionality Implemented in the Core Layer

results dataset called Results in which it stores the status, number or rows effected, and response message for each request. The results dataset is returned to the API core as a ResultSet object. The ResultSet object is an object that implements the IResultSet interface. The ResultSet is a wrapper from the .NET dataset and has two methods: Pack(oDataset As Dataset) and Unpack() As Dataset. The data access layer calls Pack() to store the results dataset in the ResultSet and the API Core calls Unpack() to retrieve the results dataset from the ResultSet. This wrapper provides a way to change the serialization mechanism used to pass data back to the API and to dynamically change serialization strategies depending on the details of a particular network architecture.

Instantiating a Collection
Instantiation of new collections is handled by one of the overloaded GetCollection() methods of the Application object. The GetCollection methods handle finding the most derived collection type and calling the collections constructor.

Our programmers never directly call New() on an API collection type, they use Application.GetCollection(). Calling New() means you instantiate a collection from a particular layer of the API, whereas GetCollection() ensures that an instance of the most derived type is returned. GetCollection first looks at the Type Cache to see if an object of the request type is already instantiated. If so, a new object of that type is instantiated and returned. If not, the code searches for the appropriate type to return. The code to search for an API type uses the entries in the <APILibraries> section of the app.config file. Each entry in this section specifies an assembly that contains API objects. The assemblies are searched in order until an object matching the specified criteria is found. Once found, the type is added to the type cache and returned. This mechanism allows you to have any number of layers in the API, implement partial layers in multiple assemblies, and add/remove layers by modifying the app.config file.

Filling a Collection with Data


A collection is filled by calling one of its overloaded Fill() methods. The basic process for filling a collection is as follows: 1. Construct the SELECT statement. The fill method first uses the state of the collection and any parameters passed to the method to construct a SELECT statement. The SELECT clause: Normally this is SELECT*. This is done so that any custom columns added to the collections table are picked-up. The exception is when the

2009 TMA Resources, Inc.

Proprietary & Confidential

Functionality Implemented in the Core Layer

FillMode flag on the collection is set to OnDemand. In this case the select clause only includes the columns that participate in the primary key of the table. Refer to <<FillMode>> for more information about the OnDemand fill mode. The FROM clause: This is always From (table name) using the collections Schema.TableName property. All joins are handled in the WHERE clause. The WHERE clause: This is built by combining a variety of sources: Any filter criteria set by adding items to the collections FILTER property. Any filter criteria passed as a parameter to the fill method. If this collection is not a top-level collection (i.e., it has a ParentObject), the relationship that joins the parent to the child is added to the WHERE clause. Any values in the Application.Context dictionary that have the UseInQuery flag = TRUE and have a matching column name in the collection are added to the WHERE clause. The ORDER BY clause: if the SortProperty has been set on the collection, its column value is added as an ORDER BY clause to the select statement. 2. Check the local cache. Once the select statement has been constructed, the fill method determines if there is already data in the local dataset that matches the criteria (See Collection-Level Data Cache on page 6). If the local dataset contains rows that match the selection criteria, that data is used to fill the collection and no call is made to the data access layer.

The check for local data uses the Select() method of the DataTable class, which does not support all possible SQL predicates. Any query that contains a BETWEEN, LIKE, or IN clause is not supported by the DataTable.Select() method and cannot be cached in the current implementation. Queries containing these predicates always issue a select statement against the database, regardless of whether or not data has already been retrieved. 3. Fetch the data from the database. If there is no data in the local cache, or the selection criteria cannot be cached, a call is made to the Application.GetData() method, which constructs the AccessToken and RequestSet objects, passes the request to the DataAccess GetData() method, and unpacks the returned ResultSet into a Dataset. This data is then merged into the collections dataset. 4. Convert data rows to BusinessObjects. Once the rows have been retrieved, either from cache or from a call to the database, the Fill() method calls FillList(), which creates an appropriately typed BusinessObject for each row in the results and adds that BusinessObject to the collections underlying list. The BusinessObjects are created by calling the Application.GetAPIItem() method for

2009 TMA Resources, Inc.

Proprietary & Confidential

Functionality Implemented in the Core Layer

the type specified by the collections ItemType property. this ensures that the mostderived item type for that collection is the one that is created. This also means that the type of collection you are working with and the type of item it contains may by implemented in different layers of the API. For example, the Customer object may be overridden in a user layer, while the Customers collection has not been. In this case, you would have a collection of type Personify.API.Generated.CustomerInfo.Customer, but each item in the collection would be of type Personify.API.User.CustomerInfo.Customer.

The BusinessObject is a wrapper that provides strongly-typed properties and business logic for an individual data row. The actual data for the business object is maintained in the data row and is pointed to via the BusinessObjects SourceRow() property.

Modifying Data in a Collection


Creating New Objects
A new BusinessObject for a collection is created by calling the collections CreateNew() method. CreateNew() finds the appropriate item type for the collection, instantiates the new object, and returns it. The BusinessObject returned from the CreateNew() method is a stand-alone object and is not part of a collection. To add the object to the collection, use the Add() method. This adds the object to the collection and adds a new data row to the collections data table to be inserted into the database. The CreateNew() and Add() methods have been combined into a single method AddNew(), which calls Add(CreateNew()). The following actions take place when a new BusinessObject is created: BuildRow() This method creates the underlying data row in the collections data table. It set the AddedBy property (ADD_OPER column) to the current user, the AddedOn property (ADD_DATE column) to the current date/time, and the ConcurrencyId property (CONCURRENCY_ID column) to 0. BuildRow then calls SetDefaults() and NewKey() and propagates column values. SetDefaults This method sets all default values for a BusinessObject. For Value type columns, the default value is taken from the default value defined for the property in the generated code. For Code (lookup) type columns, the particular code classs DefaultValue property is used. This value is typically read from the database at runtime.

To implement complex default value logic, our programmers override the SetDefaults() method, call MyBase.SetDefaults(), then implement the logic. This method is automatically called when a new object is created, but may also be called programmatically from a property set routine when a property change will result in a change in default values.

2009 TMA Resources, Inc.

Proprietary & Confidential

10

Functionality Implemented in the Core Layer

NewKey This method ensures that the BusinessObject has a unique primary key. It takes an optional Boolean parameter (TemporaryKey), which tells the routine whether to create a temporary key or the final primary key for the object. Temporary keys are used to minimize the number of round-trips to the database when creating objects. For integer and decimal columns, the code starts with the maximum value for an integer, then continually subtracts 1 from that value until it finds a value that is not already in use in the collection. For string columns, the logic is the same, but the numeric value is padded with 9s and converted to a string. This is done to minimize the possibility of key clashes with data that is already in the database and may be added to the collection by subsequent Fill() calls. When a TemporaryKey is created the HasTemporaryKey property of the BusinessObject is set to TRUE. Final keys are set by calling the AppNextNumber() stored procedure in the database for any properties of the primary key marked as AutoNumbered. This happens automatically when saving any object where the HasTemporaryKey is set.

Propagating Column Values


When BuildRow() is called for an object that has a ParentObject, the property values that participate in the foreign-key relationship with that parent object are automatically copied to the child object. In addition, any properties that have been marked with a ValuePropagationRule in the code generation schema are also copied from the parent.

Modifying Existing Objects in a Collection


Modifications to an existing object is accomplished by setting the objects properties. There are a number of automatic formatting and validation routines that can occur when a property value is set. The rules are specified for the property in the code generation schema.

Formatting Rules
Capitalization Specifies that the property value should be converted to upper, lower, or proper case and whether to always perform the conversion or only when the existing value is null. String Padding Specifies a character, padding direction, and length. Used primarily from numeric columns that are really strings (i.e., OrderNumber).

Validation Rules
Minimum and Maximum Value Applied to numeric values. An exception is thrown if the specified value falls outside the specified range. Minimum and Maximum Length For string properties, if the values length is less than the minimum an exception is thrown. If it is longer than the maximum, the value is truncated. Regular Expression Matching For string properties, if the string does not match the regular expression, an exception is thrown. Date Range For date properties, specifies that a date may be in the Past, Present, and/ or Future. An exception is thrown if the specified date fails the rule.

2009 TMA Resources, Inc.

Proprietary & Confidential

11

Functionality Implemented in the Core Layer

Code List Validation used for ICode type properties when the Validate() flag is TRUE. If the value specified does not match a code from the ICodes list, the value is ignored.

Deleting an Object from a Collection


An object is deleted by calling the collections Remove method. This removes the object from the collection and marks the underlying row for deletion when the collection is saved.

Validating the Data in a Collection


The Validate() method is used to determine if the data in a collection is valid. The Validate() method in the core BusinessObjectCollection calls the Validate() method on each item in its list. The Validate() method on the core BusinessObject class ensures that all required fields are set. When any of the Validate() methods encounter invalid data, a new entry is created in the ValidationIssues() collection on the top-level collection.

Saving Changes to a Collection


To commit collection changes back to the database the Save() method is called. Save() calls the Validate() method and if no validation issues are reported, Save() creates a new RequestSet to hold the SQL commands to update the database. The collection then calls the GetCommands() method on each of its items. The GetCommands() method on the BusinessObject creates an INSERT, UPDATE, or DELETE statement for the object and calls Save() for each of its child collections. Calling the Save() and GetCommands() methods in this way produces a hierarchically ordered set of SQL statements to update the root collection and all of its descendents. The collection then passes the RequestSet on to the Application.SaveData method, which appends the AccessToken and calls the SaveData method in the data access layer. The data access layer creates a new transaction and executes each statement in the request set. If any statement fails, the transaction is rolled back.

2009 TMA Resources, Inc.

Proprietary & Confidential

12

Functionality Implemented in the Core Layer

The following flow chart demonstrates the Save() method.

2009 TMA Resources, Inc.

Proprietary & Confidential

13

Functionality Implemented in the Core Layer

Sorting Collections
Collection sorting is accomplished by using one of the collections overloaded Sor() methods. Sort() can be called with a property name and optional sort direction, an array of property names, or an array of PropertyInfo objects. If the collection is already filled with data, the sort method re-sorts the items in the collection using the specified criteria. the sort criteria is also included as an ORDER BY clause when the collection is filled from the database. Specifying the sort criteria before filling the collection off loads the work of sorting the collection to the database server.

Finding an Object in a Collection


The BusinessObjectCollection.FindObject() and FindAll() methods find objects in an already filled collection. Both methods take PropertyName and Value as parameters. FindObject loops through the collection and returns the first item it finds that matches the criteria. FindAll returns all items that match the criteria. Both methods work only against data already in the collection, they do not fetch additional data from the database.

Overriding Context Values


The ApplicationContext object is a dictionary that contains values that are global to the currently running application. The collections Fill() method automatically applies any values in the context dictionary to the WHERE clause before fetching data from the database. This is how collections are automatically filtered for the particular Org/OrgUnitId that the user is logged in to. To prevent an item in the context from being used as a query filter, set the context items UseInQuery property to FALSE. For example, while the Customer table contains the columns ORG_ID and ORG_UNIT_ID, these columns are set to null for individuals and not used as filtering criteria. To fill a Customers collection with individuals, you must set Application.Context.OrgId.UseInQuery and Application.Context.OrgUnitId.UseInQuery to FALSE.

Specifying Collection Filters


A filter is a set of selection criteria that is applied to a collection prior to filling it with data. All collections are automatically filtered by the property values that specify the collections relation ship to its parent object and value in the application context. Additional criteria may be specified by adding FilterItem objects to the collections Filter property. A filter item is an object that specifies a property name, a relational operator, and a value. For example, to fill a Customers collection with individuals who have a last name of Smith:
oCustomers=_App.GetCollection(CustomerInfo.Customers) oCustomers.Filter.Add(LastName,Smith) oCustomers.Filter.Add(RecordType,I) oCustomers.Fill()

2009 TMA Resources, Inc.

Proprietary & Confidential

14

Functionality Implemented in the Core Layer

Filters are used to determine what data to select from the database.

Complex Search Queries


When a simple property filter on a collection is insufficient, a SearchObject is used. The SearchObject class is able to produce complex, joined queries that target a specific API collection type. To use the SearchObject, create a new instance of SearchObject, set the Target property to the type of API collection you are searching, and add values to the SearchObject s Parameter() property. The following code searches for Customers with the last name of Smith who have a good address in the state of Maryland:
oSearch=New Personify.API.Core.SearchObject oSearch.Target=oApp.GetCollection(Personify.Enumerations.NamespaceEnum.Custo merInfo,Customers) oSearch.Parameters.Add(LastName,Smith) oSearch.Parameters.Add(Addresses.State,MD) oSearch.Parameters.Add(Addresses.Detail.StatusCode,GOOD) oSearch.search()

This creates a select statement with the appropriate WHERE clauses to join CUSTOMER to CUS_ADDRESS and CUS_ADDRESS to CUS_ADDRESS_DETAIL, as well as the specified search criteria. Executing the SearchObjects Search() method fills the SearchObjects Results() dataset with the selected rows. The SearchObjects GetObjectKey() method can then be used to choose a particular row from the results and can be used to fill a collection.

2009 TMA Resources, Inc.

Proprietary & Confidential

15

The Generated Layer


The Generated Layer of the API builds directly upon the Core Layer and is the starting point for the definition of the Personify business model. Code generation works from a set of XML files, referred to as the API Model, which contain information about the tables and columns in the Personify database, as well has how those database entities are used to create the classes and properties of the API. Advantages to generating the code in this manner are: Completeness Every entity in the Personify database has a set of API objects that provide access to it. Consistency Since every API class is coded in the same way, there is consistency across the library. Stability Bugs in the generated code are apparent across all objects in the system and are easily identified and fixed. Bug fixes made in one location apply to all objects in the system. Accelerated Development Repetitive coding tasks are handled by the generated code allowing you to focus on specialized business logic for individual classes. The Generated library consists entirely of classes created with the API Generator tool. The generated library provides typing for underlying business objects, friendly names for database objects, creates default navigation paths between objects, and enforces referential integrity and data value constraints. The entire generated library can be frequently re-built at any time using the generator and this library should never include any manually written code. For each table in the database, the generated library will contain: A class derived from the TimssCollection that represents the table using the pluralized friendly name for the object. The derived TimssCollection class will have data access methods to allow fetching appropriate data into this collection with the option to fill by primary key values or a set of filtering conditions. A class derived from TimssObject that represents a row from the table using the singular friendly name for the object. The derived TimssObject class will contain a friendly-named, strongly-typed property for each column in the table. For each child relationship defined in the schema, the derived TimssObject class will contain a shortened, friendly-named property that provides access to the foreign table object using the TimssObject instance as a parent.

2009 TMA Resources, Inc.

Proprietary & Confidential

16

API Model Files

API Model Files


The API Model is the input to the code generation process.

The Code Generation Process


Code generation is accomplished by applying an XSL transformation to the API model. In this way you can apply a different transformation to the same API model input to produce various work products. The following transformations are used: Classes.xslt Produces the VB source code that makes up the generated layer. Interfaces.xslt Produces the VB source code that makes up the interfaces library. Documentation.xslt Produces HTML class library documentation.

Code Generation Tools


There are three software components that make up the Personify code generation utilities. CodeGen.dll The main code generation library. This contains the methods responsible for checking model files in and out of VSS, running the XSL transformations to generate the classes, interfaces and documentation, compiling the generated code, and synchronizing the API model with the Personify database. CodeGenCMD.exe A command line interface to CodeGen.dll. This utility is used to create the generated code at build time. CodeGenGUI.exe A windows interface to CodeGen.dll. It is used to modify the API model and re-generate code for the development environment.

Working with the Code Generator Interface


Default Behavior
When the code generator starts, it connects to the VSS database using the current Windows user ID and loads the top-level model XML file.

Command Line Parameters


Our programmers can pass the following parameters to the utility: SSDB The path to the VSS database containing the model files. SSUSER The VSS user ID to use when connecting. SSPASSWORD The VSS password to use when connecting. COREDEV Allows you to modify model information without checking out files. This option is used for testing the generator utility and should not be used for actual development. NOCONNECT The UI does not automatically connect to the VSS. You must manually connect to VSS using the menu option.

2009 TMA Resources, Inc.

Proprietary & Confidential

17

API Model Files

NOLOAD The UI does not automatically load the API model files. You must specify the model files to load using the menu option. WSROOT Identifies the root directory of the developers workspace. This should be the working directory that is mapped to the VSS root ($/) project.

2009 TMA Resources, Inc.

Proprietary & Confidential

18

Personify

Elements of the API Model


The following sections describe each element of the API Model.

Personify
The Personify element is the root of the API Model. Parent Nodes None Child Nodes ObjectModel User Interface Navigation only. There is no UI to directly edit this element.

ObjectModel
The ObjectModel element is the root element for all information related to generating code. Parent Nodes Personify Child Nodes DataTypes, Namespaces User Interface Navigation only. There is no UI to directly edit this element.

DataTypes
The DataTypes element contains a collection of DataType elements. Parent Nodes ObjectModel Child Nodes DataType User Interface Navigation only. There is no UI to directly edit this element.

DataType
Defines a common data type for use by properties in the API. The initial list of data types is derived from the date types defined in the SQL server. Data types do not directly produce any generated code. They are specify a reusable set of attributes and facets for value properties in the API. Parent Nodes DataTypes Child Nodes CapitalizationFacet, StringPaddingFacet, RegexValidationFacet, DateFacet User Interface:
Field Name SQL Name Name of the data type. Name of the type define in the SQL Server. Description

2009 TMA Resources, Inc.

Proprietary & Confidential

19

Namespaces

Field Base Type Default Value Min Length Max Length Min Value Max Value

Description API data type that is the basis for this type. Default value for the data type. For String based types, the minimum length of the string. For String base types, the maximum length of the string. For Numeric types, the minimum value of the number. For Numeric types, the maximum value of the number.

Namespaces
The Namespaces element contains a collection of Namespace elements. Parent Nodes ObjectModel Child Nodes Namespace User Interface Navigation only, there is no UI to directly edit this element.

Namespace
The Namespace element defines a Namespace in the API and corresponds directly to the Subsystems defined for Personify. Parent Nodes Namespaces Child Nodes Collection, Item, Exception, ValidationIssue User Interface:
Field Name Abbreviation License Key Name of the namespace. Subsystem abbreviation for the namespace. Holds information for enforcing licensing restrictions for API modules. Description

Collection
Defines an API Collection class. A Collection class corresponds to a table in the SQL server and inherits from Core.BusinessObjectCollection. For every Collection element, there is a matching Item element that defines the individual column properties for the table. Parent Nodes Namespace Child Nodes Properties, Methods, Events

2009 TMA Resources, Inc.

Proprietary & Confidential

20

Item

User Interface:
Field Name Item Type Interface Name Item Interface Table Name Access Caption Description Read Only Description The name of the API Collection class. The name of the API Item class that corresponds with this collection. The name of the API Interface for this class is always the same as the Collection class name (with the letter I prefixed). The name of the API Interface for this class is always the same as the Item Type name (with the letter I prefixed). The name of the SQL server table that this collection represents. The access modifier for the generated collection class: Public, Friend, Protected, or Private. Defaults to Public. English caption for the class. Description of the class. Specified whether items in the collection may be modified. This flag controls the _DisableAdd, _DisableEdit, and _DisableRemove flags on the base BusinessObjectCollection. Intended to indicate whether this collection may be instantiated as a standalone object, or only as the child of another object. At this time, all collection types may be standalone and this flag is not referenced. Intended to indicate that this collection is the primary collection (first-order object) of its namespace. Useful for dynamically generating user interface code, but not currently referenced anywhere. Specifies that this collection is to be included in the generated code.

Top-Level Collection

Primary Collection for Namespace

Publish

Item
Defines an Item class for the API. An item class corresponds to a Row in a SQL Server table and inherits from Core.BusinessObject. Parent Nodes Namespace Child Nodes Properties, Methods, Events

2009 TMA Resources, Inc.

Proprietary & Confidential

21

Properties

User Interface:
Field Name Collection Type Interface Name Collection Name Table Name Description Name of the API Item class. Name of the corresponding collection class for the item. Name of the API Interface for the item. Name of the API Interface for this items collection type. Name of the SQL Server table for which this item represents a single row.

Properties
A collection of Property elements. Parent Nodes Collection, Item Child Nodes Property User Interface Navigation only, there is no UI to directly edit this element.

Property
This represents a property on a class in the API. There are four kinds of properties that can be represented in the model: 1. Value Properties Value properties correspond directly to Columns in the SQL Server database. They represent simple data elements. Value property definitions may include one or more facets that supply additional formatting or validation rules for the property. Currently the available facets are CapitalizationFacet, StringPaddingFacet, RegexValidationFacet, and DateFacet..
Field Name API Type Access Column Name Caption SQL Type Description Default Value The name of the property. API (VB) data type of the value. Object access to the property. The SQL Server column name corresponding to the property. The generic caption name for the property. SQL Server data type for the column. A brief description, for documentation purposes, of the property. The default value for the property. Description

2009 TMA Resources, Inc.

Proprietary & Confidential

22

Property

Field Read-Only

Description This specifies that the property should be generated as a ReadOnly property. The API does not expose a means of setting the property. This specifies that the value may not be changed when the object is in the Inserted state. Inserted means that the item has been created and added to the collection, but the collection has not yet been committed to the database. This flag does not generate a ReadOnly property; a property set statement is still created when this value is True, but the logic in the core prevents changes to this property when in Inserted mode.

Read-Only on Insert

Read-Only on Update

This specifies that the value may not be changed after the original object has been committed to the database. This provides the ability to create Write-Once properties. This specifies that this property is required. All non-nullable columns in SQL Server are marked as Required. This specifies a unique constraint for this property within its collection. When this flag is checked, the core checks to ensure any value entered into this property does not already exist in the underlying table. This indicates that this property is part of the tables primary key and, if so, its position in the key. The first column in the tables primary key should have a value of 1. A value of 0 means that this property is not part of the key. For key properties, this specifies that the column is to be automatically numbered (using the APP_NEXT_NUMBER table). For string properties, this specifies the minimum and maximum length of the string. For numeric properties, this specifies the minimum and maximum value of the number. Displays whether the work on this API property is Completed, In Progress, or Pending.

Required Enforce Uniqueness

Key Position

Auto Numbered Length: Min and Max Value: Min and Max Development Status

2. Code Properties Code properties correspond to Columns in a table, but they include information about the enumerated (lookup) values for that column. This is used for

2009 TMA Resources, Inc.

Proprietary & Confidential

23

Property

columns that implement the ICode interface. A code property must have a CodeInfo child node that defines the parameters for the ICode object.
Field Name API Type Access Column Name Caption SQL Type Description Default Value Code Type The name of the property. API (VB) data type of the value. Object access to the property. The SQL Server column name corresponding to the property. The generic caption name for the property. SQL Server data type for the column. A brief description, for documentation purposes, of the property. The default value for the property. This identifies the Code Class (i.e., the class that implements the ICode interface) that handles the code. The code type is the return type for this property. This specifies that the property should be generated as a ReadOnly property. The API does not expose a means of setting the property. This specifies that this property is required. All non-nullable columns in SQL Server are marked as Required. This indicates that this property is part of the tables primary key and, if so, its position in the key. The first column in the tables primary key should have a value of 1. A value of 0 means that this property is not part of the key. For key properties, this specifies that the column is to be automatically numbered (using the APP_NEXT_NUMBER table). Displays whether the work on this API property is Completed, In Progress, or Pending. Description

Read-Only

Required Key Position

Auto Numbered Development Status

3. List Properties List properties correspond to relationships between tables in the database. For example, the CUSTOMER CUS_DEMOGRAPHIC relationship in the database is represented by the Demographics property of the Customer object in the API. A list property definition must have a Relationship child node that defines the relationship.
Field Name Access The name of the property. Object access to the property. Description

2009 TMA Resources, Inc.

Proprietary & Confidential

24

Property

Field Caption Description Target Namespace Target Collection Min Cardinality Max Cardinality Cascade Insert Cascade Delete

Description The generic caption name for the property. A brief description, for documentation purposes, of the property. Namespace of the API object that this property references. Class name of the collection type that this property references. The minimum number of items that this property refers to. If this is not required, enter 0. The maximum number of items that this property refers to. If there is no limit, enter 0. Indicates that a new item should be created when the parent is created. Indicates that the items referenced by the property should be deleted when the parent is deleted.

2009 TMA Resources, Inc.

Proprietary & Confidential

25

Property

Field Related Properties Table

Description Defines the relationship (i.e., the foreign-key) from this object to the target. This table has four columns: SourceProperty The name of the parent object. TargetProperty The name of the property of the child object. IsJoinKey Specifies that the Source/Target pair is part of the foreign-key relationship. Values that have IsJoinKey set are used by the Core to create the inner join clauses needed to fill collections. ValuePropagationRule Specifies the rule to use for copying property values from parent to child when inserting or updating the parent. Options are: Always Overwrites the value in the child object with the value in the parent object. IfNull Copies the value from the parent to the child only if the value is null on the child object. IfSame Copies the value from the parent to the child only when the value on the child is the same as the original value on the parent. IfNullOrSame Copies the value from the parent to the child if the value is null on the child object or if the value on the child is the same as the original value on the parent. Never Does not copy values from the parent to the child.

For properties that are part of the join key, the value propagation rule must be Always (i.e., being part of the join key means that the values must match between parent and child and any changes to the parent are reflected in the child). Other properties that are not part of the join key may be specified on the relationship. For example, the OrgId column. The OrgId column is not part of the tables key, but when set on a parent object, you want the value to be reflected on all child objects.

2009 TMA Resources, Inc.

Proprietary & Confidential

26

CapitalizationFacet

4. Transient Properties A transient property provides a means to reference calculated or derived information at runtime through a property statement. Transient properties are not stored in the database.
Field Name Member Name Return Type Default Value Access Caption Description ReadOnly The name of the property. The name for the private member variable that is generated to hold this propertys value. The data type of the property. The default value for the property. Object access to the property. The generic caption name for the property. A brief description, for documentation purposes, of the property. This specifies that the property should be generated as a ReadOnly property. The API does not expose a means of setting the property. Determines whether the propertys calculated information can be overridden. Description

Overridable

CapitalizationFacet
A CapitalizationFacet specifies capitalization rules for string-based, value properties. Parent Node Property Child Nodes None User Interface:
Field Capitalize Description Specifies how to capitalize the string: Preserve Take no action on the string. Upper Convert to upper case. Proper Convert to property (i.e., Name) case. Lower Convert to lower case. Specifies how the capitalization rule is applied. Always The rule is always applied. One Time The rule is only applied when the property value is changed to a different string (not just a different case of the string).

Apply Rule

2009 TMA Resources, Inc.

Proprietary & Confidential

27

StringPaddingFacet

StringPaddingFacet
Applies a padding character, with an optional prefix, to the string value using the max length specified on the string property. For example, if the OrderNumber property has a padding character of 0, a prefix of 1, and a direction of left, when the value 1234 is entered for an order number, the value will be converted to 1000000001234. Parent Nodes Property Child Nodes None

RegexValidationFacet
Specifies a regular expression that must be matched when setting the propertys value. If the new value does not match the expression, an exception is thrown. Parent Nodes Property Child Nodes None

DateFacet
Applies to value properties that are based on the Date data type. This facet provides runtime checking of a date value relative to the current date. For example, this could be used to require that a BirthDate property not be able to be set to a future date. Parent Nodes Property Child Nodes None

Methods
A collection of Method elements. Parent Nodes Collection, Item Child Nodes Method User Interface Navigation only, there is no UI to edit in this element.

Method
This element allows you to specify a method to generate on the class. The code generator uses the information to create an empty Sub or Function in the generated class. Actual implementation of the method must be done by overriding the method in the base layer. Parent Nodes Methods Child Nodes Parameters

2009 TMA Resources, Inc.

Proprietary & Confidential

28

Parameters

User Interface:
Field Name Return Type Access Overloaded Description The name of the method. The data type returned by the method. If none is specified the method is generated as a Sub rather than a Function. Code access to the method. Specifies whether or not there is overloaded parameter sets for this method.

Parameters
This element represents a set of parameters that are passed to a method or event. It is used to generate the method signature for methods and events. Parent Nodes Method, Event Child Nodes Parameter User Interface:
Field Name Type Optional Default Value Description The name of the parameter. The data type of the parameter. Indicates an optional parameter. Defines the default value for optional parameters.

2009 TMA Resources, Inc.

Proprietary & Confidential

29

Collection Interface

The Interfaces Library


The code generator creates the Interfaces library at the same time as the generated layer. The library contains an interface definition for each collection type and for each item type. These interfaces are a part of making the multi-layered API work. When working with objects in any layer of the API, you always reference the interface rather than the class definition. This allows the actual implementation of that object to reside in any layer of the API.

Collection Interface
This is a typical interface created for the AbstractAuthors BusinessObjectCollection:
Public Interface IAbstractAuthors Inherits Personify.API.Core.IBusinessObjectCollection Default Shadows ReadOnly Property Item(ByVal nIndex As Integer) As IAbstractAuthor Function CreateNew() As IAbstractAuthor Shadows Function AddNew() As IAbstractAuthor Shadows Function Add(ByVal Item As IAbstractAuthor) As Integer Shadows Sub Remove(ByVal Item As IAbstractAuthor) Overloads Sub Fill(By Val AbstractId As Long,_By Val MasterCustomerId As String, ByVal SubCustomerId As Integer) End Interface

Item Interface
This interface is created for the AbstractAuthor BusinessObject:
Public Interface IAbstractAuthor Inherits Personify.API.Core.IBusinessObject Property Property Property Property Property Property Property Property Property Property Property Property ReadOnly ReadOnly ReadOnly ReadOnly ReadOnly AbstractId() As Long MasterCustomerId() As String SubCustomerId() As Integer RoleCode() As Personify.API.Core.ICode RoleSinceDate() As Date ListingOrder() As Decimal Honorarium() As Decimal Comments() As String AllowToPublishFlag() As Boolean AllowToRecordFlag() As Boolean AllowToPhotographFlag() As Boolean AllowToInterviewFlag() As Boolean Property AddedBy() As String Property AddedOn() As Date Property ChangedBy() As String Property ChangedOn() As Date Property ConcurrencyId() As Long

2009 TMA Resources, Inc.

Proprietary & Confidential

30

Item Interface

Property CorrespondingAuthorFlag() As Boolean End Interface

2009 TMA Resources, Inc.

Proprietary & Confidential

31

Division of Database Tables

The Base Layer


The Base Layer of the API is where business logic is implemented. All code in the base layer is hand-written; it contains no generated code. To implement specific logic for a particular business object or collection, a developer must create a new class that inherits from the business object and overrides existing properties or methods. The base layer can be used to enforce complex business rules, override default behavior in the generated library, create custom classes, properties, relationships, etc. For example, the base layer could contain a class called Individuals that derives from the Customers class and enforces the rule that the RecordType property is set to I. The base library is also where complex logic such as calculating order discounts, tax, shipping, etc. are coded.

Division of Database Tables


Each table is mapped to a collection in the API. The table is placed in its appropriate namespace based upon the subsystem to which it belongs. The following table shows some example of the tables and where they are placed in the API structure.
Table Name Product Order_Master Lck_Holding_Detail Customer Member_Group Subsystem Product Order LockBox Customer Membership Namespace Timss.TimssAPI.ProductInfo.Product Timss.TimssAPI.OrderInfo.OrderMaster Timss.TimssAPI.LockBoxInfo.LockBoxHolding Detail Timss.TimssAPI.CustomerInfo.Customer Timss.TimssAPI.MembershipInfo.Membergrou p

2009 TMA Resources, Inc.

Proprietary & Confidential

32

Common Functions/Properties of API Collections

Common Functions/Properties of API Collections


CreateNew and AddNew
This creates a new instance of the object contained in the collection class. For example, OrderMasters.CreateNew creates a new instance of the OrderMaster object. Use this in conjunction with AddNew to save new records in the database. In another example, to save a new customer record, the following code needs to be written:
Dim mcolCustomers as New Timss.TimssApi.Customers.Customer(AppContext) Dim moCustomer as Timss.TimssApi.Customers.Customer moCustomer=mColCustomers.CreateNew() moCustomer.MasterCustomerId = 0001 moCustomer.SubCustomerId = 0 mcolCustomers.AddNew(moCustomer) mcolCustomers.Save

Fill
This method fills a collection (for example, fetching data from the database table). This function is overloaded to facilitate data fetching with almost any condition (for example, fetching all orders created on July 1, 2008):
Dim mColOrderMasters as New Timss.TimssAPI.Order.OrderMasters(AppCOntext) Dim oFilter as new Timss.ApiBase.TimssFilter oFilter.Add(order_date, 07-01-2008) mColOrdermasters.fill(nothing, oFilter)

To fetch a specific customer record:


Dim moColCustomers as new Timss.Api.Customers.Customer(AppContext) moColCustomers.Fill(1234, 0)

Accessing Dataset and DataRow Properties


The structure of the API is based on the dataset. The collections are directly mapped to the data tables and the data rows are directly mapped to the objects. Essentially, the underlying engine that supports the API structure is a Dataset. For example, accessing a dataset would resemble OrderMasters.Dataset and accessing a data row would resemble OrderMasters.Item(0).SourceRow.

2009 TMA Resources, Inc.

Proprietary & Confidential

33

Programming Tasks

Programming Tasks
The following highlights the tasks that are performed by the developer for each API collection/object.

Existing Code Base


The existing Personify windows application remains the primary source of information for coding the base API objects. However, since the individual screens are responsible for data access, user interface management, and business logic, it is often difficult to determine the parts of the logic in the screens that need to go to the API. The following are some guidelines to help make that determination: Code that deals with data access (i.e., selecting data from a table, initiating a database transaction, committing changes to the database, etc.) is handled by the API core and should not be coded into the base. However, if there is code to select dependent data from the database given the state of the object in focus, you should make sure that a List Property exists on the API object to retrieve the dependent collection. Code that deals with selecting data to populate combo boxes, list boxes, or other enumeration type controls should not be coded into the base. You must ensure that an ICode property exists and is configured correctly for that enumerated data. Code that deals with formatting and validating data should be included in the code generator schema, if possible, and coded into the base layer if not possible. Code that deals with retrieving a new key for a data row should not be ported (this is covered by the API core). Code that manipulates the visible or enabled properties of controls on a form should be given careful consideration. Often these are indicators that a particular property may not be modified for a given state. If so, this code should be ported to mark the property as ReadOnly in the same way the control was disabled. Code that creates new data rows given the state of a particular parent row should be ported to the base code. This code should be implemented on the property get statement for the child object. Code that deletes rows from the database should not be ported. Code that deals with QBE should not be ported.

Verifying the Code Generation Metadata


Since the majority of the metadata used to create the generated layer has been reverseengineered from the database, it is important to review and verify its correctness.

Value Properties
Each value property on an object should be reviewed to determine that it has the correct data type, has the correct default, min and max values, and that its required and autonumber flags are correctly set.

2009 TMA Resources, Inc.

Proprietary & Confidential

34

Programming Tasks

Code Properties
Each code property on an object should be reviewed to determine that it has been configured correctly. For codes that are read from the APP_CODE table, this means checking that the Subsystem and Type parameters on the code set to their correct values and that the Option1/2/3 parameters are referenced if they are used for that code.

List Properties
Each list property on an object should be reviewed to ensure that the cardinality is set correctly, that it is returning the correct API type, and that the join key is set up correctly. For zero-to-one or one-to-one relationships, the return type of the list property should be the interface name of the related properties item type. For zero-to-many or one-to-many relationships, the return type should be the interface name of the collection type for the related property. For example, the relationship of Customer to Demographics is one-tomany, therefore the property should return a type of Personify.API.CustomerInfo.CustomerDemographics. The relationship of Customer to Employer is one-to-one, therefore the property should return a type of Personify.API.CustomerInfo.ICustomer.

Applying Default Values


Most of the defaults for value properties can be set in the metadata for the generated code. There are cases, however, where default values are dependent on other properties within the object or one of its related objects. In those cases, the SetDefaults() method should be overridden and the logic for defaulting the value should be implemented there. Since SetDefaults() is called as soon as the object is created, you may also call it at some later point when more knowledge about the object is available.

Ensuring Referential Integrity


A large portion of the base code should be devoted to ensuring referential integrity among API objects. This means that your code should handle automatically verifying, and possibly creating or deleting, related objects in response to actions against an object. For example, a row in the PRODUCT table requires there to be one, and only one, related entry in one of the product subsystem tables (INV_PRODUCT, MBR_PRODUCT, SUB_PRODUCT, etc.) depending on the subsystem of the product. Consequentially, when the Subsystem property of the Product object is changed, logic in the Product object must verify that one of the product subsystem properties (InventoryProduct, MembershipProduct, SubscriptionProduct, etc.) contains a valid entry. The code must determine when it is appropriate to change the Subsystem property, take the appropriate action when the property is changed, or disallow the property change when that action would violate integrity rules.

Implementing Calculated Members


It is the responsibility of the developer to implement business logic that calculates values for API objects. Calculated members are modified based on changes to one or more properties

2009 TMA Resources, Inc.

Proprietary & Confidential

35

Programming Tasks

of the object. If multiple properties are involved, the code that calculates the member should be placed in a separate function. This function is then called from each of the properties set methods. Many methods should be callable independently of the standard interface methods. An indicator of this is whether or not the existing user interface has a button to perform the methods action. Methods such as CalculateShipping(), CalculateTax(), RecalculateOrder(), etc. are such methods. These should be marked as Public and Overridable, so that they can be called independently of the standard interface and their behavior may be overridden by a subsequent API layer.

Providing Shortcut Methods and Properties


Short-cut methods and properties encapsulate complex interactions into easier to use methods. However, they should never be used as a replacement for the standard interface methods. Examples of shortcut methods are: OrderMaster.AddProduct() Adds a new order detail line to an order using the specified product. Customer.PrimaryAddress() Retrieves the primary address for a customer. Customer.MemberSince() Provides a date value that represents when this customer became a member.

2009 TMA Resources, Inc.

Proprietary & Confidential

36

Understanding Validation Issues


This section describes the infrastructure for validation processing in Personify.

Definitions of Terms Used in this Section


Term API Developer Definition An internal TMA Resources programmer who implements business logic in the API. This logic may be implemented in the Base layer or any subsequent layers. Any program that makes use of the Personify API (e.g., the user interface, a batch process, or any customer program accessing the API). For the purposes of this section, the programmer responsible for implementing the consumer. This could be an internal TMA Resources programmer, or an external developer working on some other application referencing the API. An object that represents additional information, a warning, a problem that must be addressed by the consumer, or a question that requires a response from the consumer.

Consumer

Customer

Validation Issue

A Validation Issue is a Class


In the Personify API, Validation Issues are implemented as classes that inherit from TIMSS.API.Core.IssueBase. They can be implemented in any layer of the API, but will most likely be implemented in either the Core (in the case of a generic issue) or in the Base layer.

Naming Standards for Validation Issues


Validation Issues can be identified easily. TMA Resources has created all of its Validation Issues to end in the word Issue. For example, OrderInfo.ProductOutofStockIssue, CustomerInfo.InvalidAddressIssue, etc.

Validation Issue Classes Are Not Generated Code


Previously, Validation Issues were created as part of the code generation process in Personify, however, this is no longer practiced by TMA Resources programmers. Generic issues (i.e., issues that display simple informational messages or a simple yes/no response) are coded in the Core layer of the API. Validation Issues that are not simple must be manually coded by the API developer in the base or subsequent layers. However, manually created base layer validation issue classes should always inherit from the Core layer.

2009 TMA Resources, Inc.

Proprietary & Confidential

37

Validation Issues Are Not Messages


Personify Validation Issues are not simply message strings. They are a stand-alone class implemented in the API and can have their own properties and methods, implement complex behaviors, and provide multiple messages to the consumer. A single issue can be coded to report issues for a variety of situations. For example, for a subscription product there can be a number of problems regarding the start and end dates (start date greater than end date, start date missing, end date missing, etc.). All of these issues can be handled by a single Validation Issue class that accepts the StartDate and EndDate values. The issue class then determines the appropriate message to display. Therefore, there is no need to create issue classes for each specific message.

Validation Issues Are Not Exceptions


Validation Issues are used to report/react business logic errors, while Exceptions are used to report/react system errors. When an Exception is thrown, it means that you have stepped out of the path of the code and an unexpected situation has occurred. In the case of a Validation Issue, a problem may have occurred but it is something that could normally happen during the course of running the program. The API will identify Validation Issues, create the appropriate issue class alerting the consumer of the issue, and take the default action.

2009 TMA Resources, Inc.

Proprietary & Confidential

38

Validation Issues During Runtime


Validation Issues are created at runtime by the API wherever the API developer saw fit to raise an issue. Each top-level BusinessObjectCollection in the API has a ValidationIssues collection property containing all of the outstanding issues for that collection, any child collections, and any respective BusinessObjects in those collections. Additionally, the API developer can also access Validation Issues belonging to a specific Business Object.

Setting Message ID Numbers


The IssueBase class accepts a message ID on one of its overloaded constructors. Classes that inherit from IssueBase are coded with the specific message ID numbers they are using in the issue class. Message IDs used in issue classes are referenced by private constants in the issue class. If additional messages are needed within the issue, the API core Application.GetMessage() function provides cached access to messages based on MessageId and Subsystem.

Use of AutoResponses
The core Application object has an AutoResponses property containing a collection of automatic issue responses. It is the responsibility of the consumer to populate the collection of autoresponses.

Clearing Validation Issues


Issues that do not require a response are automatically cleared by the base Validate() method before it performs its validation. In addition, the Assert() function clears its issue when the condition passed to the assert method is false.

Continue Processing or Exit


For some issues, further processing is stopped when the issue is encountered. For example, when trying to calculate a shipping amount, if no shipping address is specified, an issue is raised and processing is stopped. For other issues, the issue will be raised and processing continues. For example, if you are creating a LabelName for a customer and the LastName property is missing, you can still continue producing the LabelName while taking the missing information into account. It is the responsibility of the API developer to determine whether or not processing should continue when a particular issue is encountered and this is dependent upon the severity of the issue and the cost of continuing the operation. If the issue is an informational message or warning message that does not require a response, the program should continue with its processing.

2009 TMA Resources, Inc.

Proprietary & Confidential

39

If the issue is an Error condition, the program will most likely not be able to continue. If the issue is a Question (i.e., a prompt to the consumer), the process may continue with a default response to the issue or exit the process and re-evaluate the issue when next called.

2009 TMA Resources, Inc.

Proprietary & Confidential

40

Classes

Validation Issue Infrastructure


The following identify the classes that support the Validation Issue handling in the Core layer of the API.

Classes
AutoResponsesCollection
The AutoResponsesCollection class contains a list of automatic responses to validation issues. The collection is loaded and referenced by the API Core Application object. The collection is implemented as a hash table that is keyed by API item type/issue type. For example, an auto-response fro the product out of stock issue that is coded in the base OrderInfo namespace is keyed in the hash table as OrderInfo.OrderMaster/ OrderInfo.ProductOutOfStockIssue. It is the responsibility of the consumer to load the autoresponses collection with the appropriate responses for that collection. The API developer may check for an auto response using the HasResponse and GetResponse methods.

Example
From within the OrderInfo.OrderMasters collection, the following call determines if an auto response exists for the ProductOutOfStockIssue.
Global.App.AutoResponses.HasResponse(Me.ItemType, GetType (ProductOutOfStockIssue)

Methods
Name Add Remove HasResponse GetResponse Description Adds an auto response to the collection. Removes the response from the collection. Returns TRUE if the requested response exists in the collection. Returns the StandardResponseType value of the response. If the response does not exist in the collection StandardResponseType, NONE is returned.

IssueBase
The IssueBase class is the base class for all validation issues.

2009 TMA Resources, Inc.

Proprietary & Confidential

41

Classes

Properties
Name Caption Description A short descriptive caption for the issue. This is used by UI programs as a dialog title when displaying the issue. If not overridden, the caption defaults to the Severity of the issue. A string that uniquely identifies the issue within an issues collection. The issue base class requires that the key be passed on the constructor. Inherited classes may automatically generate this key as appropriate. For example, the InformationMessageIssue in the Core generates a GUID for the key and combines the class name and additional key, if applicable, to arrive at the Unique key for the issue.

Key

It is up to the API developer to determine if an issue needs an additional key. If the additional key is passes to the constructor, it is included as part of the Key. Message This is the text message displayed for the issue. Overloaded constructors on IssueBase allow this to be specified as either a string message or as a MessageId number. Both constructors also take a number of issue parameters as well, allowing this message to be used as a format string. In addition, an inherited issue class may choose to override the message property so that more complex logic may be implemented to show a more appropriate message. The reference property provides a place for the creator of the issue to store contextual information about the issue. For example, if the issue is a question about a particular product, the API developer may choose to store the product object in the reference property. This way, when the question is answered, the API developer can take action against the stored product value. The response property returns the Responses.SelectedResponses property. This supports legacy validation issue code. This is a Boolean data type indicating whether a response is required for the issue. The severity of the issue. See IssueSeverityEnum for a list of values.

Reference

Response

ResponseRequired Severity

2009 TMA Resources, Inc.

Proprietary & Confidential

42

Classes

Name Responded ParentGuid AdditionalKey

Description This property indicates whether a response has been received from the consumer of the API for the issue. This returns the GUID of the parent object of the object that raised the validation issue. When identical issues exist in the same object, this property allows the user to obtain the AdditionalKey associated with the issue.

IssueEventArgs
The IssueEventArgs class is used when the IssueAdded event is raised from the IssueCollection class. These events are intended to be used by the consumer to react to the raising of validation issues.

Properties
Name Issue Description The issue that was added to the collection

IssueResponse
The Issue Response class represents a single response to the issue.

Properties
Name Description Description The text description of the response. This is the string that displays to the end user in an interactive application when the issue provides a choice of responses. The value for the description may be set using a string or message ID. Shared property that returns an empty response. The reference property provides a place where the creator of the issue can store contextual information about the response. For example, if an issue is asking the consumer to choose between a list of alternate products, the API developer may choose to store the ProductId of each choice in the Reference property. Converts the Value property, which is a string, to one of the value in StandardResponseEnum. If the Value property cannot be converted into a StandardResponseEnum, then StandardResponseEnum.None is returned.

Empty Reference

StandardResponseValue

2009 TMA Resources, Inc.

Proprietary & Confidential

43

Classes

Name Value

Description The sting value of the response. This value is determined by the API developer when the issue is created. The developer may use the StandardRespons values (i.e., OK, Cancel, Yes, No, etc.) or any other sting value (i.e., a product code, customer ID, etc.).

IssueResponsesCollection
The IssueResponsesCollection contains a list of IssueResponse objects. It is typically referenced via the Responses property of an Issue object.

Properties
Name Item Description Returns a single IssueResponse object from the collection using either the responses string value, the StandardResponseEnum value, or the numeric index of the item within the collection. Returns the response that was chosen by the consumer. If no choice has been made SelectedResponse returns Nothing. Returns the response marked as the default response for the issue. Returns TRUE if the consumer has responded to the issue.

SelectedResponse DefaultResponse Responded

Methods
Name Add Remove Contains IndexOf Description Adds a new response to the collection. Removes the response from the collection. Returns TRUE if the collection contains the specified response. Returns the integer index of the response within the collection. If the response is not found, it returns a negative number.

IssuesCollection
The IssuesCollection is a collection of validation issues. The IssuesCollection class is referenced from the within a BusinessObject or BusinessObjectCollection by referencing the ValidationIssues property of the object. There is only one IssuesCollection for each top-

2009 TMA Resources, Inc.

Proprietary & Confidential

44

Classes

level API collection. Each member of the top-level collection, all of its child collections, and all of their items point to the root-level ValidationIssues collection.

Properties
Name Item Description Returns an individual issue from the collection either via the issues key or the numeric index of the issue within the collection. Set to TRUE by default. When this is set to FALSE, the ValidationIssueEvent will not be raised. This can be used to make the UI ignore the event when the issue is generated by the API.

TriggerValidaitonIssueEvent

Methods
Name Assert Description Accepts a conditional expression and an issue. If the condition is TRUE the issue is added to the collection. If the condition is FALSE the issue is removed from the collection. Shortcut method that removes all issues from the collection that do not require a response. This adds a new issue to the collection. By default, when an issue is added, the Add method checks the AutoResponses collection determine if there are any auto responses for the issue. If there is, the Add method sets the selected response on the issue to the appropriate value before adding it to the collection. If the auto response value is Ignore, the Add method ignores the issue and does not add it to the collection. Removes the issue from the collection. Removes all of the issues from the collection. Returns TRUE if the specified issue is in the collection. Returns the number of issues in the collection that have a severity of ERROR. The default save method checks this value before attempting to save a collection. If the ErrorCount > 0, the save method does not attempt to save the collection. Returns the numeric index of the issue within the collection. If the issue is not found, IndexOf returns a negative number.

ClearResponseNotRequiredIs sues Add

Remove RemoveAll Contains ErrorCount

IndexOf

2009 TMA Resources, Inc.

Proprietary & Confidential

45

Classes

Events
Name IssueRaised Description This event occurs whenever a new issue is added to the collection. It is used by the consumer to react to new validation issues. This event occurs when the issues collection is cleared. It is used by the consumer to display the list of current outstanding issues.

IssuesReset

IIssue
This is the interface implemented by all validation issues. This interface is implemented by IssueBase.

Properties
Name Caption Description A short descriptive caption for the issue. This is used by UI programs as a dialog title when displaying the issue. If not overridden, the caption defaults to the Severity of the issue. A string that uniquely identifies the issue within an issues collection. The issue base class requires that the key be passed on the constructor. Inherited classes may automatically generate this key as appropriate. For example, the InformationMessageIssue in the Core generates a GUID for the key and combines the class name and additional key, if applicable, to arrive at the Unique key for the issue.

Key

It is up to the API developer to determine if an issue needs an additional key. If the additional key is passes to the constructor, it is included as part of the Key. Message This is the text message displayed for the issue. Overloaded constructors on IssueBase allow this to be specified as either a string message or as a MessageId number. Both constructors also take a number of issue parameters as well, allowing this message to be used as a format string. In addition, an inherited issue class may choose to override the message property so that more complex logic may be implemented to show a more appropriate message.

2009 TMA Resources, Inc.

Proprietary & Confidential

46

Classes

Name Reference

Description The reference property provides a place for the creator of the issue to store contextual information about the issue. For example, if the issue is a question about a particular product, the API developer may choose to store the product object in the reference property. This way, when the question is answered, the API developer can take action against the stored product value. The response property returns the Responses.SelectedResponses property. This supports legacy validation issue code. This is a Boolean data type indicating whether a response is required for the issue. The severity of the issue. See IssueSeverityEnum for a list of values. This property indicates whether a response has been received from the consumer of the API for the issue. This returns the GUID of the parent object of the object that raised the validation issue. When identical issues exist in the same object, this property allows the user to obtain the AdditionalKey associated with the issue.

Response

ResponseRequired Severity Responded ParentGuid AdditionalKey

IIssuesCollection
The interface implementedd by the IssuesCollection class.

Properties

Name Item

Description Returns an individual issue from the collection either via the issues key or the numeric index of the issue within the collection. Set to TRUE by default. When this is set to FALSE, the ValidationIssueEvent will not be raised. This can be used to make the UI ignore the event when the issue is generated by the API.

TriggerValidaitonIssueEvent

2009 TMA Resources, Inc.

Proprietary & Confidential

47

Classes

Methods
Name Assert Description Accepts a conditional expression and an issue. If the condition is TRUE the issue is added to the collection. If the condition is FALSE the issue is removed from the collection. Shortcut method that removes all issues from the collection that do not require a response. This adds a new issue to the collection. By default, when an issue is added, the Add method checks the AutoResponses collection determine if there are any auto responses for the issue. If there is, the Add method sets the selected response on the issue to the appropriate value before adding it to the collection. If the auto response value is Ignore, the Add method ignores the issue and does not add it to the collection. Removes the issue from the collection. Removes all of the issues from the collection. Returns TRUE if the specified issue is in the collection. Returns the number of issues in the collection that have a severity of ERROR. The default save method checks this value before attempting to save a collection. If the ErrorCount > 0, the save method does not attempt to save the collection. Returns the numeric index of the issue within the collection. If the issue is not found, IndexOf returns a negative number.

ClearResponseNotRequiredIs sues Add

Remove RemoveAll Contains ErrorCount

IndexOf

Events
Name IssueRaised Description This event occurs whenever a new issue is added to the collection. It is used by the consumer to react to new validation issues. This event occurs when the issues collection is cleared. It is used by the consumer to display the list of current outstanding issues.

IssuesReset

2009 TMA Resources, Inc.

Proprietary & Confidential

48

Classes

IssueSeverityEnum
The IssueSeverityEnum identifies the severity of the issue.
Name Information Warning Description The is extra information provided to the consumer and is only used if no response is necessary. Warns the consumer about a particular action. Similar to Information, but allows the consumer to display the message differently. Used when a response from the consumer is needed. Identifies the issue as an error. Errors may or may not include responses. If a BusinessOjects issues collection contains error issues, the save method does not attempt to save the object.

Question Error

StandardIssueResponseEnum
The StandardIssueResponseEnum represents a list of standard responses to issues. An issue may or may not use the standard responses, or may use a combination of standard and custom responses. It is the responsibility of the API developer to determine the correct set of responses for a particular issue. Valid values are: Cancel Continue Ignore No None OK Retry Yes

2009 TMA Resources, Inc.

Proprietary & Confidential

49

Classes

Core Validation Issues


The following issue classes are coded in the API core.

PropertyMissingIssue
This issue is raised when an object requires a property value, but that value has not been set. The Reference property of the issue contains the object that is missing the property and the issue provides a property name property as well.

BusinessObjectPropertyMissingIssue
This issue is similar to the PropertyMissingIssue, except that the Reference property is strongly typed to an IBusinessObject object. The name of the missing property is stored in the issue as well. This issue is raised by the core Validate() methods when checking that all required properties on a business object are set.

InvalidPropertyValueIssue
This issue is raised when a consumer attempts to set a property to a value that is not valid for that property. This may be a violation of the minimum or maximum length of a string, the minimum or maximum value for a number, a setting outside of a specified date range, etc. The issue is raised by the various Property Setter methods in the core BusinessObject.

YesNoIssue
This is a generic issue that automatically adds the YES and NO responses to its responses collection. This issue is not used by the core, but is available for the base layer developers to inherit from.

DuplicateObjectIssue
This issue identifies that a duplicate object has been detected. It is raised by the DuplicateCheck() process in the Core.

2009 TMA Resources, Inc.

Proprietary & Confidential

50

Classes

Validation Issue Examples


This section displays a number of example of validation issues within a few different subsystems. It covers issues in which a users response is required in order to determine the proper course of the business flow. This section will answer the following questions for each validation issue example: When is this issue thrown? What is the message/response? How do you resolve the issue? What are the implications of this issue (may not apply to all examples)?

This section is only a sampling of validation issues and is not intended to cover every validation issue in Personify. The following examples describe the a sampling of validation issues handled by Personify. Each validation issue is a specific class designed and coded in the API.Base.<Namespace>.<ValidationIssue Class> by the API developer to handle different business scenarios. For example, Order related validation issues are coded in OrderValidationIssues.vb within the OrderInfo namespace as shown below:

2009 TMA Resources, Inc.

Proprietary & Confidential

51

Classes

If you have to extend the base functionality and a new Issue of response type is required to be added for the order entry process, you can add the new class in the following namespace of your Customer Layer.

All validation issues class names should end with Issue. It is not a mandatory requirement, but helps in identifying an Issue class among other objects when using context sensitive help.

The namespace definition is not required in the code if you set up the root namespace in the project properties.

2009 TMA Resources, Inc.

Proprietary & Confidential

52

OrderInfo Validation Issue Examples

OrderInfo Validation Issue Examples


MeetingRegistrationIssue
When is this issue thrown?
This issue is raised internally by the API when a meeting or session is added to the order if the business rules dictate it. Meetings and sessions normally have a limit on the amount of people that can be registered and waitlisted. When a meeting or a session is added to the order/shopping cart, the system validates whether or not seats are available. If the seats are not available, the system then checks to see if seats are available on the waitlist. If both the registrar and waitlist are full, the system does not allow the meeting or session to be added to the order. This validation can be thrown for these reasons: There is no capacity and no waitlist capacity available. There is no capacity, but the waitlist is available. There is no capacity available, but the product allows you to Override Capacity (not available on the Web). When you place an order for a meeting/session for which the registration date has passed. When you exceed the maximum number of tickets allowed for a session.

ProductOutofStockIssue
When is this issue thrown?
The ProductOutOfStockIssue is raised when a product is selected on an order detail line. The OrderDetail object is responsible for raising the issue. The constructor for the issue class requires only a product ID and product name. The product ID is used for the Reference property and the product name is used as a parameter for constructing the message. The class determines the unique key for the issue and contains constants defined for all of the messages that it needs. The class also contains a CanBackOrder property and an AddAlternateProduct method. These are used by the OrderDetail object to control the behavior of the ProductOutOfStockIssue.

What is the message/response?


When the CanBackOrder flag is set to TRUE, the issue class adds a response, with the appropriate message and a response value of Continue to its responses collection. It then sets this as the default response for the issue. When AddAlternateProduct is called, a new

2009 TMA Resources, Inc.

Proprietary & Confidential

53

OrderInfo Validation Issue Examples

response is added to the responses collection specifying the appropriate message and using the ID of the alternate product as the value for the response.

2009 TMA Resources, Inc.

Proprietary & Confidential

54

OrderInfo Validation Issue Examples

Invoking the ProductOutOfStockIssue


The following code shows how the OrderDetail object would invoke the ProductOutOfStockIssue. This would be called when the order detail object determines that the product is out of stock. The code creates a new ProductOutOfStockIssue, passing the

2009 TMA Resources, Inc.

Proprietary & Confidential

55

OrderInfo Validation Issue Examples

product ID and product name on the constructor. It then sets the CanBackOrder flag to true, and adds three alternate products.

2009 TMA Resources, Inc.

Proprietary & Confidential

56

OrderInfo Validation Issue Examples

InvalidDateRangeIssue
InvalidDateRangeIssue is an issue class that reports an invalid date range. The issue accepts an Owner object, a StartDate, and EndDate on the constructor. It uses the Owner object to create a unique key for the issue an stores the StartDate and EndDate in private variables. The class does not set a message string in the constructor, rather, it overrides the message property and returns one of three messages depending on the contents of the StartDate and EndDate properties.

2009 TMA Resources, Inc.

Proprietary & Confidential

57

CustomerInfo Validation Issue Examples

CustomerInfo Validation Issue Examples


AddressValidationIssue
This validation issue alerts the user as to the results of the Address Validator. The Address Validator application is used to validate customer addresses.

When is this issue thrown?


This issue is thrown when the Address Validator completes its function. For example, Group1 has completed its run and needs to inform the user of its results.

What is the message/response?


There are two messages. If the address validation is successful, a message similar to, Address has been validated. No errors. Continue? displays. If issues arise with the Address Validator or an exception has been raised, a message similar to, Address cannot be validated followed by the error/exception displays.

How do you resolve this issue?


If the address validation is successful, no action must be taken. If an error was raised by the Address Validator, the address must be corrected and re-validated. If an exception occurs, contact your System Administrator.

What are the implications of this issue?


The address is either validated by the system or is rejected.

2009 TMA Resources, Inc.

Proprietary & Confidential

58

CustomerInfo Validation Issue Examples

SegmentWithMembersDisabledIssue
When is this issue thrown?
This validation issue is raised when the user attempts to disable a segment definition for which there are existing members.

What is the message/response?


Members exist for this segment definition. Do you want to turn off Segmentation? The message also displays the rule, description, and qualifiers for the segment definition. This requires a Yes/No response.

How do you resolve this issue?


Since this is a Yes/No issue, the user must choose to either leave the segment definition as is or turn off segmentation.

What are the implications of this issue?


The segment definition is turned on/off based upon the users response.

SegmentChangeWithMembersIssue
When is this issue thrown?
This issue is thrown when the user attempts to change a Segment Definition for which there are existing members.

What is the message/response?


Members exist for this segment definition. Do you want to continue with the change? The message also displays the rule, description, and qualifiers for the segment definition. This requires a Yes/No response.

How do you resolve this issue?


Since this is a Yes/No issue, the user must choose to either leave the segment definition as is or allow for modifications to the segment definition.

What are the implications of this issue?


The segment definition is turned on/off based upon the users response.

UpdateSubCustomerStatusToReflectMasterCustomerStatusIssue
This validation issue updates the Customer Status Code of Sub Customer when the master record is being updated.

When is the issue thrown?


This issue is thrown when the user updates the Customer Status Code and the customer has Sub Customer records linked to it.

What is the message/response?


Do you want to change the child record status to (modified status)?

2009 TMA Resources, Inc.

Proprietary & Confidential

59

CustomerInfo Validation Issue Examples

This requires a Yes/No response.

How do you resolve this issue?


Since this is a Yes/No issue, the user must choose to either update the sub customer record(s) with the modified Customer Status Code or not.

What are the implications of this issue?


The Customer Status Code of the sub customer record(s) are updated or not based on the users response.

MarkAddressAsBillToORShipToIssue
This validation issue alerts the user of a potential duplicate primary customer address and updates of the customers Primary Address flag depending on the users response.

When is this issue thrown?


This issue is thrown when the user adds a new address or edits an existing address and marks the address as the primary address when a primary address already exists for the customer.

What is the message/response?


Another address is marked as the primary #1# address. Should the new address become the primary #1# address? This requires a Yes/No response.

How do you resolve this issue?


Since this is a Yes/No issue, the user must choose whether or not to update the primary address flag.

What are the implications of this issue?


The primary address flag of the customer may be modified based upon the users response. A customer can only have one primary address.

CreateMultipleLinksToPrimaryAddressIssue
When is this issue thrown?
This validation issue is thrown when a user creates a new address and attempts to link that address to another customer.

What is the message/response?


Cannot link to the company record entered because this companys primary address is already linked to customer #1#. Link this record to #1# as well? This requires a Yes/No response.

How do you resolve this issue?


Since this is a Yes/No issue, the user must decide whether or not to proceed with linking the addresses.

2009 TMA Resources, Inc.

Proprietary & Confidential

60

CustomerInfo Validation Issue Examples

EmailExistAsPrimaryForAnotherCustomerIssue
When is this issue thrown?
This issue is raised when a user creates a new primary email address for a customer, attempts to save the record, and the email address is already being used as the primary email address for another customer record.

What is the message/response?


Email address already exists in Personify as a primary email for customer #1#. Do you want to set this email as primary email for current customer? This requires a Yes/No response.

How do you resolve this issue?


Since this is a Yes/No isssue, the user must decide whether or not to use the email address as the primary email address for both customers.

PrimaryEmployerAlreadyExistsIssue
This validation issue alerts the user to the fact that the customer already has a primary employer on record and updates the primary employer flag based upon the users response.

When is this issue thrown?


This issue is raised when the user creates a new primary employment relationship for a customer and attempts to save the record.

What is the message/response?


Primary employment already exists, do you want to update existing primary employer information with new information? This requires a Yes/No response.

How do you resolve this issue?


Since this is a Yes/No issue, the user must decide whether or not to update the primary employment flag of either of the customers employment relationship records.

What are the implications of this issue?


The newly created relationship record is either set as the primary employment relationship or not based upon the users response. There can be only one primary employer for a single customer record. Customer records can have multiple, non-primary employer records.<Check validity of this statement>

PrimaryContactAlreadyExistsIssue
This validation issue alerts the user to the existence of a primary contact relationship for the customer and updates the primary contact flag of the customers relationship depending on the users response.

2009 TMA Resources, Inc.

Proprietary & Confidential

61

CustomerInfo Validation Issue Examples

When is this issue thrown?


This issues is raised when a user creates a new primary contact relationship for a customer and attempts to save the record.

What is the message/response?


Primary contact already exists, do you want to update existing primary contact information with new information? This requires a Yes/No response.

How do you resolve this issue?


Since this is a Yes/No issue, the user must decide whether or not to update the primary contact flag of either of the customers contact relationship records.

What are the implications of this issue?


The newly created relationship record is either set as the primary contact relationship or not based upon the users response. There can be only one primary contact relationship for a single customer record. Customer records can have multiple, non-primary employer records. < CHECK>

DuplicateCustomerMatchesFoundIssue
This validation issue alerts the user of a potential duplicate customer match based on criteria set up for the application to match a duplicate customers and contains a list of the possible duplicate customer records. The user can choose to continue with the customers creation or select one of the identified duplicates.

When is this issue thrown?


The issue is raised upon the users saving of a newly created customer record.

What is the message/response?


Duplicate Customer Match Found for <LabelName>. Do you want to continue? This requires a Yes/No response.

How do you resolve this issue?


If the Personify UI displays a screen with a data grid displaying the duplicate customers found, the user can either select one of the presented customer records or continue saving the record. If not using the Personify UI, the validation issue will contain DuplicateCustomerIds property, which displays a list of the potential duplicate customers.

What are the implications of this issue?


The newly created customer record can either be saved as is or the user can select one of the duplicate matches to work with.

2009 TMA Resources, Inc.

Proprietary & Confidential

62

S-ar putea să vă placă și