Tuesday, May 25, 2010

Creating PeopleSoft CRM Worker using CDM Classes


What is the best way to create and maintain workers to PeopleSoft CRM? The correct way to synchronize workers to PeopleSoft CRM is using the Workforce services. This works fine when using PeopleSoft HCM, but what about when your HCM application is non-PeopleSoft? In our case where are integrating PeopleSoft CRM HR Helpdesk with SAP HCM and P&I HCM.

The Workforces services can still be used in conjunction with HCM applications other then PeopleSoft HCM, but the downside is that the services are too much PeopleSoft oriented. They have a PSCAMA record as audit orientation and most important, they are effective dated. Most other applications incorporate effective dating as start date and end date.
In other words to use the Workforce services with other applications then PeopleSoft HCM give a lot of overhead.

The next logical option is to use Component Interfaces. However the Worker component is secured via PeopleCode not to be used to load workers.

This brings us to the famous and feared CDM classes (Customer Data Modal). After some research I found the reputation of the CDM classes is totally incorrect. Using the CDM classes to load and maintain the complex data modal of PeopleSoft CRM is childishly simple.

First let me give you an introduction the CDM class hierarchy.

OBJECTCOLLECTION CLASS

Before talking about the CDM classes in detail,  we need to understand the Object Collection class. This class isn’t a part of the hierarchy because it does not touch any CDM database object directly. However, it is extremely important since none of the CDM application classes could function properly without it.
The ObjectCollection does exactly what its name implies; it is a collection of Objects. The class is a utility to instantiate CDM objects and keeps them in a single place. We can then save the collection, which will loop through all of the objects in the collection and save them. This class also acts to cache the objects.

ObjectCollection has three different modes in which the Individual sub classes can be instantiated. They are “ADD”, “UPDATE”, and “CONVERT”. We use Add mode to create a new object, “Update” mode to modify an existing object, and “Convert” mode to add a new role to an existing object and use the new role to instantiate the object.

Refection CLASS

The Reflection class is a utility to get the list Properties and Methods of its extended class at runtime. This feature is used to define mappings from the CDM to the flattened summary tables, and define Quick Create templates.

BOABSTRACT CLASS

The CDM application classes are frequently used by Component Interfaces. As a result, the classes need to incorporate searching. This class provides a search ability for its extend classes.

BO CLASS

BO class is the core base application class for BORM management. It encapsulates data and processing specific to a Business Object. In other words, it manages data for the following tables: BO, BO_ROLE, BO_REL, BO_CM, BO_CM_USE, and CM. While data is inserted into these tables, the BO Class also has to maintain data integrity.

BC CLASS

The BC class is sub class of BO class, and a base class that is referenced in other classes. It inherits from its base classes all the properties and methods. In addition, The BC class allows for managing the Purchasing Options of a Business contact as well Customer information such as Customer ID, Customer Status, Currecny Code, etc….

INDIVIDUAL CLASS

The Individual class is a sub class of the BC class. This  class hold all Person data such as Person ID, Sex, Title, Birthday, etc. Most of the BORM related methods in the Individual class all have an equivalent method in the BO class. However, the methods in the individual are simple and easier to use compared to the methods in the BO class since it requires less input parameters.

WORKER CLASS

The Worker object is inherited from the Individual class. It has the same business logics and processing of the online Worker Component. All the transactions that are initiated by this object will be tied to the Worker Role.

So by creating a Worker object you have access  to all public methods and properties of BO, BC, Individual and Worker.Putting this all together, results in the next peace of PeopleCode to create a Worker in PeopleSoft CRM.

import RB_CDM:INDIVIDUAL:WORKER:Worker;
import RB_CDM:ObjectCollection;

Component RB_CDM:ObjectCollection &oObjectCollection;

method createpersonViaCDM
/+ &PersonReq as Record +/

Local RB_CDM:INDIVIDUAL:WORKER:Worker &oWorker;

Local string  &NewPersonID;
Local number &NewBOID;
Local number &nNameSeq, &nProfileCMSeq;
Local Record &rName , &rWorkerName, &rJob, &rCMDetail;
Local Row &AssJobRow;

try

&oObjectCollection = create RB_CDM:ObjectCollection();
&oWorker = &oObjectCollection.getWorker("", 0, True, False, "ADD", "");

&oObjectCollection.PrimaryObject = &oWorker;

/* Person: Indivudual Class properties */
&oWorker.PersonSETID = "SHARE";
&oWorker.ContactFlag = "I";
&oWorker.LanguageCode = &PersonReq.LANGUAGE_CD.Value;
&oWorker.EmployeeID = NumberToString("%06.0", GetNextNumberWithGapsCommit(RC_LAST_NBR_TBL.RC_LAST_NBR, 99999999999, 1, "WHERE RC_LAST_NBR_TYPE = 'EMPL'"));
&oWorker.Sex = &PersonReq.SEX.Value;
&oWorker.CommunicationMethod = "C";
&oWorker.SalutationCode = &PersonReq.SALUTATION_CD.Value;
&oWorker.PreferreddNofication = "E";
&oWorker.SourceInd = "CRM";
&oWorker.PersonMarket = "GBL";
&oWorker.Birthday = &PersonReq.BIRTHDATE.Value;
&oWorker.DO_NOT_CONTACT = "N";
&oWorker.DO_NOT_EMAIL = "N";
&oWorker.DO_NOT_MAIL = "N";
&oWorker.DO_NOT_CALL = "N";

/* Add a Name for a Person */
&rWorkerName = CreateRecord(Record.BO_NAME);

&rWorkerName.FIRST_NAME.Value = &PersonReq.FIRST_NAME.Value;
&rWorkerName.LAST_NAME.Value = &PersonReq.LAST_NAME.Value;

&nNameSeq = &oWorker.addPersonName(&rWorkerName, True);

/* Add Roles 1=Person, 4 =Worker, 86=Employee */
&oWorker.addBORole(1);
&oWorker.addBORole(4);
&oWorker.addBORole(86);

/* Set initial Job record fields */
&rJob = CreateRecord(Record.RD_WRKR_JOB);
&rJob.EFFDT.Value = &PersonReq.JOB_EFFDT.Value;
&rJob.JOB_INDICATOR.Value = "P";
&rJob.EMPL_STATUS.Value = &PersonReq.EMPL_STATUS.Value;
&rJob.SOURCE_IND.Value = "CRM";
&rJob.REG_TEMP.Value = "R";
&rJob.FULL_PART_TIME.Value = &PersonReq.FULL_PART_TIME.Value;
&rJob.SETID_DEPT.Value = &PersonReq.SETID.Value;
&rJob.DEPTID.Value = &PersonReq.DEPTID.Value;
&rJob.SETID_LOCATION.Value = &PersonReq.SETID.Value;
&rJob.LOCATION.Value = &PersonReq.LOCATION.Value;
&rJob.SETID_JOBCODE.Value = &PersonReq.SETID.Value;
&rJob.JOBCODE.Value = &PersonReq.JOBCODE.Value;
&rJob.HOLIDAY_SCHEDULE.Value = &PersonReq.HOLIDAY_SCHEDULE.Value;
&rJob.SUPERVISOR_ID.Value = &PersonReq.SUPERVISOR_ID.Value;
&rJob.OFFICER_CD.Value = "N";
&rJob.MANAGER_LEVEL.Value = "9";

/* Add new Assignment row and Job row */
&AssJobRow = &oWorker.AssignmentHandler.AddNewAssignmentAndJob(86, &rJob);

/* Create Contact method for primairy mail */
&rCMDetail = CreateRecord(Record.DERIVED_RD_MAIL);
&rCMDetail.CM_PURPOSE_TYPE_ID.Value = 27;
&rCMDetail.EMAIL_ADDR.Value = &PersonReq.EMAIL_ADDR.Value;

&nProfileCMSeq =&oWorker.addContactMethod(4, &rCMDetail, 4, True, %Date);

/* Save (Worker) ObjectCollection */
&oObjectCollection.Save();

/* Get created BOId and PersonId */
&NewPersonID = &oWorker.PersonID;
&NewBOID = &oWorker.BOID;

End-method;

Some footnotes:
  • It is extremely important to declare the Objectcollection object as a component variable and naming it &oObjectCollection. The CDM classes reference this variable by that name. Naming the Objectcollection another name will result in errors.

  • Al classes have an Save method, which will save all pending data in the object to database. Always use the &oObjectCollection.Save() method. This will save all objects within the class.

  • Read this RedPaper on Metalink for detailed information on the the CDM Classes.

No comments:

Post a Comment