The FieloPLT.MemberService class includes eleven methods:
Toggle Managers (toggleManagers)
static void FieloPLT.MemberService.toggleManagers (List<Id> memberIds, String action)
You can designate one or more Organization Contributor Members as managers of their Organization Member. This endpoint allows you to set Organization Contributor Members as managers.
Parameters
Here you'll find an example of how the API can be used and a definition of it's parameters:
List<Id> memberIds = new List<Id>();
for(FieloPLT__Member__c m : [SELECT Id From FieloPLT__Member__c]){
memberIds.add(m.Id);
}
String action = 'true';
FieloPLT.MemberService.toggleManagers(memberIds, action);| Parameter | Type | Description |
|---|---|---|
| memberIds | List<Id> | List of member's IDs to choose from. |
| action | String | When true, member is set as Manager. |
Return Value
As the method is of the type void, nothing is expected to be returned.
| Type | Description |
|---|---|
| Void | Nothing is returned. |
Although nothing is expected to be returned, you can examine if the operation was successful by checking if the selected member was actually set as the manager by either querying the field 'member.FieloPLT__IsManager__c' on the database or simply going on the Organization Member page to see if the field Manager is checked.
FieloPLT__Member__c:{Id=a0Y4W0000HODvYUAX, FieloPLT__IsManager__c=true}Exceptions
Errors can occur when you use the endpoint. Use the message description to troubleshoot them.
| Type | Description |
|---|---|
| Exception | When no Member Id is given (member is null). Add a valid Member Id. |
| FieloException | When the selected member is either Blocked or Inactive. Make sure the member is Active. |
Block/Unblock Members (blockUnblock)
static void FieloPLT.MemberService.blockUnblock (List<Id> memberIds, String action)
You can prohibit individual members from participating in a program by blocking them. This endpoint allows you to block or unblock existing members.
Parameters
Here you'll find an example of how the API can be used and a definition of it's parameters:
List<Id> memberIds = new List<Id>();
for(FieloPLT__Member__c m : [SELECT Id From FieloPLT__Member__c]){
memberIds.add(m.Id);
}
String action = 'false';
FieloPLT.MemberService.blockUnblock(memberIds, action);| Parameter | Type | Description |
|---|---|---|
| memberIds | List<Id> | List of Members IDs. |
| action | String | When set to true, member will be blocked. |
Return Value
As the method is of the type void, nothing is expected to be returned.
| Type | Description |
|---|---|
| Void | Nothing is returned. |
Although nothing is expected to be returned, you can examine if the operation was successful by checking if the selected member was actually blocked by either querying the field 'member.FieloPLT__status__c' on the database or simply going on the Organization Member page to see if the field Manager is checked.
FieloPLT__Member__c:{Id=a0Y4W0000HODvYUAX, FieloPLT__status__c=Blocked}Exceptions
Errors can occur when you use the endpoint. Use the message description to troubleshoot them.
| Type | Description |
|---|---|
| Exception | When no Member Id is given (member is null). Add a valid Member Id. |
| FieloException | When the selected member is already Blocked. |
Recalculate Member Level (calculateMembersLevel)
static void FieloPLT.MemberService.calculateMembersLevel (Set<Id> memberIds)
Recalculates Levels for each Member. If any Member, or Level data/criteria change, Level evaluates the new information again.
Parameters
| Parameter | Type | Description |
|---|---|---|
| memberIds | Set<Id> | Set of Member IDs to calculate Level. |
Return Value
| Type | Description |
|---|---|
| Void | Void. |
Only active Levels will be evaluated.
List<FieloPLT__Member__c> members [SELECT Id FROM FieloPLT__Member__c LIMIT 10];
Set<Id> memberIds = new Set<Id>();
for(FieloPLT__Member__c member : members){
memberIds.add(member.Id);
}
FieloPLT.MemberService.calculateMembersLevel(memberIds);Expire Total Points (expireTotalPoints)
static void FieloPLT.MemberService.expireTotalPoints (Set<Id> memberIds)
It enables to expire all Points from a specific Member. Points must have Total Expiration Mode defined.
Parameters
| Parameter | Type | Description |
|---|---|---|
| memberIds | Set<Id> | Set of Member IDs to expire their Points. |
Return Value
| Type | Description |
|---|---|
| Void | Void. |
Set<Id> memberIds = new Set<Id>();
for(FieloPLT__Member__c m : [SELECT Id From FieloPLT__Member__c]){
memberIds.add(m.Id);
}
FieloPLT.MemberService.expireTotalPoints(memberIds);Expire Points (expireMemberPointsByType)
static void FieloPLT.MemberService.expireMemberPointsByType (Set<Id> memberIds, Id pointType)
Allows expiring all Points from a specific Member. Any custom Point Types must be already defined in order to expire them.
Undefined Point TypeIf Point Type is not established, all Points which have status Approved will expire.
Parameters
| Parameter | Type | Description |
|---|---|---|
| memberIds | Set<Id> | Set of Member IDs to expire the Point Type. |
| pointType | Id | Point Type ID. |
Return Value
| Type | Description |
|---|---|
| Void | Void. |
Set<Id> memberIds = new Set<Id>();
for(FieloPLT__Member__c m : [SELECT Id From FieloPLT__Member__c]){
memberIds.add(m.Id);
}
Id pointType = [SELECT Id FROM FieloPLT__PointType__c limit 1].Id
FieloPLT.MemberService.expireMemberPointsByType(memberIds, pointType);Register Members: Registration Step 1 (register)
static PageReference FieloPLT.MemberService.register (FieloPLT__Member__c member, String registrationType, Id ownerId)
It enables you to customize Members registration. It represents the first part of the registration process (Registration Step 1): it creates a Member and the related applicable Salesforce Accounts and Contacts.
Parameters
| Parameter | Type | Description |
|---|---|---|
| member | FieloPLT__Member__c | Member to create. |
| registrationType | String | Type of Salesforce Account used for registration. This value can be: Standard Account, Person Account or Defined Account |
| ownerId | Id | Salesforce User ID, which is the owner of the created Salesforce Account. |
Return Value
| Type | Description |
|---|---|
| Pagereference | Null. If call from a Visualforce page, it refreshes the page. |
Exceptions
| Type | Description |
|---|---|
| DMLException | When Member, Salesforce Account or Salesforce Contact creation fails. |
| FieloCustomException | When Registration Type is a Person Account but functionality is not available or When e-mail field is null. |
FieloPLT__Member__c member = new FieloPLT__Member__c(FieloPLT__Name__c = 'John Smith', FieloPLT__Email__c = '[email protected]');
try{
FieloPLT.MemberService.register(member, 'Standard Account', UserInfo.getUserId());
}catch(Exception e){
ApexPages.addMessage(new ApexPages.Message(severity.ERROR, e.getMessage()));
}Register Members: Registration Step 2 (finishRegistration)
static void FieloPLT.MemberService.finishRegistration (FieloPLT__Member__c member)
It allows you to finish the registration process (Registration: Step 2) by including new Member fields such as address, country, phone number, etc. It enables to update data from Member entered during the first part of the registration process (Registration Step 1). It also creates the Salesforce User (unless Approval Workflow is established).
PreconditionMember must have a related Salesforce Contact, its status must be Pending User and no Salesforce User must be linked to it.
Parameters
| Parameter | Type | Description |
|---|---|---|
| member | FieloPLT__Member__c | Member already created with the applied changes. |
Return Value
| Type | Description |
|---|---|
| Void | Void. |
Exceptions
| Type | Description |
|---|---|
| FieloCustomException | When Member is NULL and/or Member ID is either invalid or already related to a Salesforce User. |
FieloPLT__Member__c member = [SELECT Id FROM FieloPLT__Member__c WHERE Status__c = 'Approved'];
member.Country__c = 'USA'
try{
FieloPLT.MemberService.finishRegistration(member);
}catch(Exception e){
ApexPages.addMessage(e);
}
Clone MembersWhen using the API from Triggers, clone Members as follows:
For (FieloPLT__Member__c record : (List<FieloPLT__Member__c>) Trigger.New) { FieloPLT member = record.clone(true); FieloPLT.MemberService.finishRegistration( member ); }
Create Member and User from Salesforce Contacts (createMemberAndUserFromContacts)
static Map <Id, String> FieloPLT.MemberService.createMemberAndUserFromContacts (Set<Id> contactIds, String type, Id programId)
Creates Members from Salesforce Contacts, as long as Member type and Program are established.
If field UserCreationClass__c is defined in Program, Salesforce User is also created.
Parameters
| Parameter | Type | Description |
|---|---|---|
| contactIds | Set<Id> | ID of Salesforce Contact. |
| type | String | Must be one of these Member types: Individual Account, Organization Account or Organization Contributor |
| programId | Id | ID of the Program where the Member belongs to. |
Return Value
| Type | Description |
|---|---|
| Map<Id,String> | Map of errors from Salesforce Contact IDs. If operation is successful, value is an empty map. |
Exceptions
| Type | Description |
|---|---|
| FieloException | When Member is already linked to a Salesforce Contact, when either Member type or Program is invalid or when Salesforce Contacts are not selected. |
Set<Id> contactIds = new Set<Id>();
for(Contact c : [SELECT Id From Contact]){
contactIds.add(m.Id);
}
Id programId = [SELECT Id FROM FieloPLT__Program__c limit 1].Id
String memberType = 'Individual Account';
Map<Id, String> results = FieloPLT.MemberService.createMemberAndUserFromContacts(contactIds, memberType, programId);Accept Agreement (acceptCurrentAgreement)
static void FieloPLT.MemberService.acceptCurrentAgreement (Id memberId)
It enables a Member to accept an Agreement whose status is Current. Agreement must belong to the Member's Program.
Parameters
| Parameter | Type | Description |
|---|---|---|
| memberId | Id | ID of the Member. |
Return Value
| Type | Description |
|---|---|
| Void | Void. |
FieloPLT__Member__c member = [SELECT Id FROM FieloPLT__Member__c WHERE FieloPLT__Email__c = '[email protected]'];
FieloPLT.MemberService.acceptCurrentAgreement(memberId);Merge Members (mergeMember)
global static Map<Id,String> mergeMember(Map<Id,Id> mapMembersMerge, Boolean recalculateLevels, Boolean reparentOnline, String confJson)
Use this method to consolidate duplicate Member records in the same program. The first parameter takes a hash map of member pairs to merge, where each key is a "child" member ID and each value is a "parent" member ID. Child members will be merged into parent members on a field-by-field basis according to your specifications.
Before executing, you can check out the default configurations that will determine how individual Member fields are reconciled during the merging process, as well as which related records are to be updated or deleted after the merge.
Go to Salesforce Setup and, via quick find, navigate to Static Resources. Under the FieloPLT namespace, view the JSON file called MemberMerge. You'll see something like this:
{
"memberMergeFields": [
{
"apiName": "FieloPLT__Account__c",
"mergeOption": "StatusBased"
},
{
"apiName": "FieloPLT__Agreement__c",
"mergeOption": "NonEmptyNewest"
},
{
"apiName": "FieloPLT__Contact__c",
"mergeOption": "StatusBased"
},
{
"apiName": "FieloPLT__Email__c",
"mergeOption": "Newest"
},
{
"apiName": "FieloPLT__LastTransactionDate__c",
"mergeOption": "MaxValue"
},
{
"apiName": "FieloPLT__IsManager__c",
"mergeOption": "StatusBased"
},
{
"apiName": "FieloPLT__OrganizationAccount__c",
"mergeOption": "StatusBased"
},
{
"apiName": "FieloPLT__User__c",
"mergeOption": "StatusBased"
}
],
"relatedObjects": [
{
"apiName": "FieloPLT__BadgeMember__c",
"relationshipFields": "FieloPLT__Member__c"
},
{
"apiName": "FieloPLT__EmailAlert__c",
"relationshipFields": "FieloPLT__Member__c"
},
{
"apiName": "FieloPLT__Event__c",
"relationshipFields": "FieloPLT__Member__c"
},
{
"apiName": "FieloPLT__MemberSegment__c",
"relationshipFields": "FieloPLT__Member__c"
},
{
"apiName": "FieloPLT__Redemption__c",
"relationshipFields": "FieloPLT__Member__c"
},
{
"apiName": "FieloPLT__Transaction__c",
"relationshipFields": "FieloPLT__Member__c"
}
],
"deleteObjects": [
{}
],
"overrides": "false"
}Using the above JSON tree as a model, you can write your own files to add to or override these configurations. Start by creating a text file with the extension .json.
In "memberMergeFields", each key-value pair specifies a Member field ("apiName") and which value should be kept when merging two members ("mergeOption"). If, during merging, a field is found that is not included in your configurations, the merged record will retain the value of the parent member. You can add additional fields following this format:
{"apiName": "//API name of field", "mergeOption": "//A merge option from the table below"}Check out all the different merge options you can apply in your configs:
| Merge Option | Description |
|---|---|
| Master | Use the value from the parent record. This is the default merge option for any fields not mentioned in your configs. |
| Slave | Use the value from the child record. |
| MaxValue | Keep the larger of the field values. Can be used only on Number and Date fields. |
| MinValue | Keep the smaller of the field values. Can be used only on Number and Date fields. |
| Sum | Use the sum of the field values from both records. Can be used only on Number fields. |
| Oldest | Keep the value that has been there the longest. |
| Newest | Keep the value that was modified most recently. |
| NonEmptyOldest | Keep whichever field contains a value. If both contain a value, keep the value that has been there the longest. |
| NonEmptyNewest | Keep whichever field contains a value. If both contain a value, keep the value that was modified most recently. |
| NonEmpty | Use the value from the parent record, unless that field is empty, in which case the value from the child record is used. |
| Concatenate | Join together the field values from both records. Can be used only on Text fields. Note: You can add the "merger" attribute to define what character will separate the joined values.e.g. "merger":" " to separate with a space |
| TrueValue | If either value is true, the merged field will be true. Can be used only on Boolean fields. |
| FalseValue | If either value is false, the merged field will be false. Can be used only on Boolean fields. |
| StatusBased | Use the value from the record whose Status (FieloPLT__Status__c) is retained in the merged member. See Status Merging for details. |
Some fields, like Status (FieloPLT__Status__c), Membership Type (FieloPLT__Type__c) and point balance fields are merged automatically according to hardcoded rules:
Status Merging
| Status | Submitted for Approval | Rejected | Pending User | Active | Banned | Opt-out | Blocked |
| Submitted for Approval | Submitted for Approval | Submitted for Approval | Pending User | Active | Banned | Most recent1 | Most recent1 |
| Rejected | Submitted for Approval | Rejected | Pending User | Active | Banned | Opt-out | Most recent1 |
| Pending User | Pending User | Pending User | Pending User | Active | Banned | Most recent1 | Most recent1 |
| Active | Active | Active | Active | Active | Banned | Date dependent2 | Date dependent3 |
| Banned | Banned | Banned | Banned | Banned | Banned | Banned | Banned |
| Opt-out | Most recent1 | Opt-out | Most recent1 | Date dependent2 | Banned | Opt-out | Date dependent4 |
| Blocked | Most recent1 | Most recent1 | Most recent1 | Date dependent3 | Banned | Date dependent4 | Blocked |
(1) The status of the most recently updated record, based on LastModifiedDate, will be kept. (2) The status that will be kept depends on the Join Date and Opt-out Date:
- If both Opt-out Date and Join Date are present and the Opt-out Date is after the Join Date, the resulting status will be Opt-out.
- If both Opt-out Date and Join Date are present and the Opt-out Date is before the Join Date, the resulting status will be Active.
- If Join Date is empty, but Opt-out Date and Last Transaction Date are present, and the Opt-out Date of the opted-out member is after the Last Transaction Date of the active member, the resulting status will be Opt-out.
- If Join Date is empty, but Opt-out Date and Last Transaction Date are present, and the Opt-out Date of the opted-out member is before the Last Transaction Date of the active member, the resulting status will be Active.
- If both Opt-out Date and Join Date are empty, the status of the most recently updated record will be kept (based on LastModifiedDate).
- If Opt-out Date and Join Date are the same, the parent record's status will take precedence.
- If both Join Date and Last Transaction Date are present and the Join Date of the active member is after the Last Transaction Date of the blocked member, the resulting status will be Active.
- If both Join Date and Last Transaction Date are present and the Join Date of the active member is before the Last Transaction Date of the blocked member, the resulting status will be Blocked.
- If both Join Date and Last Transaction Date are empty, the status of the most recently updated record will be kept (based on LastModifiedDate).
- If Join Date and Last Transaction Date are the same, the parent record's status will take precedence.
- If both Opt-out Date and Last Transaction Date are present and the Opt-out Date of the opted-out member is after the Last Transaction Date of the blocked member, the resulting status will be Opt-out.
- If both Opt-out Date and Last Transaction Date are present and the Opt-out Date of the opted-out member is before the Last Transaction Date of the blocked member, the resulting status will be Blocked.
- If both Opt-out Date and Last Transaction Date are empty, the status of the most recently updated record will be kept (based on LastModifiedDate).
- If Opt-out Date and Last Transaction Date are the same, the parent record's status will take precedence.
Membership Type Merging
The merging of Membership Types (FieloPLT__Type__c) goes by the following rules:- If the parent record is an Individual Member and the child is either an Individual or Organization Contributor, the merged member will be Individual.
- If both records are Organization Contributor Members, the merged member will be, as well.
- If both records are Organization Members, the merged member will be, also.
- No other combinations are allowed. If attempted, the MergeMembersInvalidTypes exception will be thrown.
Point Balance Merging
The merging of point balances occurs online (when possible) in the following manner:- If the resulting status of the merged member is Banned, an Expiration transaction is generated and point balances are set to 0.
- If the resulting status of the merged member is Opt-out, the sum of the parent and child point balances will be available in the merged member until the opt-out expiration period (if defined) has passed. If there is no opt-out expiration period, or once the period has passed, an Expiration transaction is generated and point balances are set to 0.
- For all other resulting statuses, the sum of the parent and child point balances are granted to the merged member.
In "relatedObjects", each key-value pair specifies a related object ("apiName") and the Member lookup field on that object ("relationshipFields") that is to be updated if it references a child record that has been merged. You can specify additional related objects using this format:
{"apiName": "//Object API name", "relationshipFields": "//API name of Member lookup field"}
Currently, the Tracker, Challenge Member and Level Member objects cannot be reparented. Member levels are recalculated, however, as part ofmergeMember.
Next, in "deleteObjects", you can specify any objects whose records you want deleted if they have a lookup to a child Member record. In the same format as in "relatedObjects", each key-value pair specifies a related object ("apiName") and the Member lookup field(s) on that object ("relationshipFields"):
{"apiName": "//Object API name", "relationshipFields": "//API names of Member lookup fields separated by commas"}
Objects from other Fielo librariesIf you want to specify
"relatedObjects"and/or"deleteObjects"from Fielo apps (such as Learning and Invoicing), you'll want to place them in a separate file, as you'll associate those configurations with those app libraries later on.
Finally, in "overrides", you can specify whether your configurations will add to or replace any existing configurations in the same library. If you set it to "true", the configurations will supersede any others. If "false", they will be applied along with any other configurations in the library. Note that the default config has "overrides": "false". So, in your file, you can choose to add your own configurations to the default ones (by setting "overrides" to "false") or override all the default configs with your own file (by setting "overrides" to "true").
Once your config file is ready, you can upload it to Salesforce as a static resource. Then, link it to a library. If your configs include Member fields and/or any related objects from FieloPLT, you'll want to link them to the FieloPLT library. If your configs are for objects from Fielo apps (like Learning and Invoicing), link them to the corresponding library (e.g. FieloELR or FieloPRP).
With all of that done, you can finally start using the memberMerge method.
PreconditionBefore calling this method, be sure to include the following check in all of your Apex triggers:
if(! FieloPLT.MemberService.isMerging){ //trigger logic }This is to ensure that your triggers aren't executed during merging.
Parameters
| Parameter | Type | Description |
|---|---|---|
| mapMembersMerge | Map<Id,Id> | The hash table of Member records that are to be merged, where the key is the ID of the child record and the value is the ID of the parent record. |
| recalculateLevels | Boolean | When set to true, the calculateMembersLevel method is automatically called to recalculate the Levels of merged members. |
| reparentOnline | Boolean | When set to true, the reparentRelated method is automatically called to update references to deleted members in related records. This is to ensure the data integrity of all records with Member lookups. |
| confJson | String | Deprecated. Pass null in this parameter. |
Return Value
| Type | Description |
|---|---|
| Map<Id,String> | If operation is successful, an empty hash map is returned. If errors occur during execution, a hash map is returned with keys containing the IDs of the member records that presented issues and values containing the corresponding error messages. No members are merged if any errors occur during execution. |
Exceptions
| Type | Description |
|---|---|
| MergeMemberAutoFields | Execution was attempted with configurations that lacked one or more fields required to be merged, such as Status (FieloPLT__Status__c), Type (FieloPLT__Type__c) and point balance fields. |
| MergeMemberInvalidMergeOption | Execution was attempted with configurations that included invalid merge options on one or more fields. |
| MergeMemberInvalidField | Execution was attempted with configurations that included invalid API names. |
| MergeMemberInvalidMergeOptionValue | Execution was attempted with configurations that applied the MaxValue or MinValue options to non-numeric or non-date fields. |
| MergeMemberInvalidMergeOptionSum | Execution was attempted with configurations that applied the Sum option to non-numeric fields. |
| MergeMemberInvalidMergeOptionConcatenate | Execution was attempted with configurations that applied the Concatenate option to non-text fields. |
| MergeMemberInvalidMergeOptionBoolean | Execution was attempted with configurations that applied the TrueValue or FalseValue options to non-Boolean fields. |
| MergeMemberFieldApiMissing | Execution was attempted with configurations that included empty or null API names. |
| MergeMemberMergeOptionRequired | Execution was attempted with configurations that included empty or null merge options. |
| MergeMemberDifferentMergeOption | Execution was attempted with multiple configuration files that specified different merge options for the same field(s). |
| MemberMergeMissingConfiguration | Execution was attempted, but no configuration files were found. |
| InvalidJsonResources | Execution was attempted, but one or more configuration files found in Static Resources were improperly formatted. |
| MergeMemberNoInput | No members were found in the mapMembersMerge parameter. |
| MemberIdNotFound | One or more invalid IDs were found in the Member hash map. |
| MergeMemberNoMasterId | One or more child record IDs (i.e. keys) in the Member hash map did not have a corresponding parent record ID (i.e. value). |
| MergeMembersDifferentProgram | A merge was attempted of members of different programs. Only members who are in the same program can be merged. |
| MergeMembersInvalidTypes | A merge was attempted of members with incompatible Membership Types. See Membership Type Merging for details. |
| MergeMemberAlreadyMerged | A merge was attempted involving at least one member with an incompatible Status (FieloPLT__Status__c). Members with a status of Merged, Pending Merge and Anonymized cannot be merged. |
| MergeMemberError | All other errors will throw this exception along with the error message that Salesforce returns. |
Map<Id,Id> membersToMerge = new Map<Id,Id>{'ID1' => 'ID2', 'ID3' => 'ID4'};
FieloPLT.MemberService.mergeMember(membersToMerge, true, true, null);Reparent Related Records (reparentRelated)
global static Boolean reparentRelated(Map<Id,Id> mapMembersMerge)
This method ensures the data integrity of records that have lookups to merged members. For all records containing the ID of a duplicate member that has been removed during a merge, this method will replace those lookups with the correct member ID after merging is completed.
It is called automatically by mergeMember when that method's reparentOnline parameter is set to true. If reparenting cannot be finished online, or reparentOnline is set to false, this method is executed offline in a batch process.
While reparenting has yet to be completed, the child members will have the status Pending Merge. Once reparenting is completed for all related records, their status changes to Merged.
