Bevor ich die Besonderheiten der Lead-Konvertierung beschreibe, mache ich einen kurzen Exkurs in das Thema "Personenaccounts".
Personenaccounts ist ein Salesforce-Feature, das die Differenzierung zwischen den Business- und Consumer-Kunden ermöglicht.
Business-to-business (B2B):
- Standard (muss nicht aktiviert werden)
- ein Account mit einem oder mehreren Kontakten
Business-to-consumer (B2C):
- muss bei Bedarf von Salesforce aktiviert werden
- ein Account mit einem einzigen Kontakt
Wird ein Personenaccount (B2C) erstellt, sind zwangsweise 2 Datensätze (Account und Contact) in Salesforce sichtbar. Die Basis der beiden Datensätze ist dieselbe. Das bedeutet, jede Contact-Änderung hat sofort Auswirkung auf den Account und umgekehrt.
Das Öffnen eines B2C-Kontaktes aktiviert den Account-Tab.
Bei der Konvertierung von Leads wird das Feld "Company" ausgewertet.
Auszug aus der Testklasse:
Personenaccounts ist ein Salesforce-Feature, das die Differenzierung zwischen den Business- und Consumer-Kunden ermöglicht.
Business-to-business (B2B):
- Standard (muss nicht aktiviert werden)
- ein Account mit einem oder mehreren Kontakten
Business-to-consumer (B2C):
- muss bei Bedarf von Salesforce aktiviert werden
- ein Account mit einem einzigen Kontakt
Wird ein Personenaccount (B2C) erstellt, sind zwangsweise 2 Datensätze (Account und Contact) in Salesforce sichtbar. Die Basis der beiden Datensätze ist dieselbe. Das bedeutet, jede Contact-Änderung hat sofort Auswirkung auf den Account und umgekehrt.
Das Öffnen eines B2C-Kontaktes aktiviert den Account-Tab.
Bei der Konvertierung von Leads wird das Feld "Company" ausgewertet.
Ein Eintrag im Feld "Company" erzeugt nach der Konvertierung einen B2B-Account.
Bleibt Company dagegen leer, wird ein Personenaccount (mit einem Contact) erstellt.
Was muss ich eigentlich bei der Lead-Konvertierung tun, wenn weitere Objekte am Lead dranhängen?
- Diese Unterobjekte müssen programmatisch mittels Trigger umgehängt werden.
Glücklicherweise müssen wir im Backend die beiden Account-Typen, B2B und B2C, nicht unterscheiden. Nach der Lead-Konvertierung wird unter anderem das Feld "ConvertedContactId" mit der neuen Kontakt-ID gefüllt. Diese Id wird bei der Neu-Zuordnung von Unterobjekten genutzt.
Auszug aus dem Lead-Trigger:
/**********************
CONSTRUCTOR
***/
public
f42_Lead_Helper(){
//*******
OBJECT NAME , LOOKUP FIELD NAME (for LEAD) | LOOKUP FIELD NAME (for
Contact) **********************
mapObjectsToUpdateAfterConversion
= new
map<String,
String>();
mapObjectsToUpdateAfterConversion.put('Unterobjekt1',
'Lead__c|Contact__c');
mapObjectsToUpdateAfterConversion.put('Unterobjekt2',
'Lead_Name__c|Name__c');
}
/*++++++++++++++++++++
startAfterConversionProcess
+++*/
public
void
startAfterConversionProcess(list<Lead>
lstObj, map<Id,
Lead>
mapObjOld){
//
map with all converted lead ids and account ids
map<Id,
id> mapConvertedContactByLead = new
map<Id,
Id>();
//
Initialize list with sObject to update
list<sObject>
lstObjUpdate = new
list<sObject>();
//
Leads updated
if(mapObjOld
!= null){
for(Lead
l :lstObj){
// was the current lead
converted?
if(l.IsConverted
== true
&& mapObjOld.get(l.id).IsConverted
!= true){
// check the corresponding
Person Account Id
if(l.ConvertedContactId
!= null){
mapConvertedContactByLead.put(l.id,
l.ConvertedContactId);
}
}
}
}
//
get all related objects, reassign to the person account and put into
update list
if(!mapConvertedContactByLead.isEmpty()){
reassignRecords(lstObjUpdate,
mapConvertedContactByLead);
if(!lstObjUpdate.isEmpty()){
update
lstObjUpdate;
}
}
}
/*------------------
reassignRecords
---*/
private
void
reassignRecords(list<sObject>
lstObjUpdate, map<Id,
id> mapConvertedContactByLead){
//
loop through all settings defined in constructor
for(String
s :mapObjectsToUpdateAfterConversion.keySet()){
String
sFields = mapObjectsToUpdateAfterConversion.get(s);
String
sFieldLead = sFields.substringBefore('|'); //
LEAD Lookup Field
String
sFieldContact = sFields.substringAfter('|'); //
CONTACT Lookup Field
//
all converted lead ids
set<Id>
setIdLeads = new
set<Id>(mapConvertedContactByLead.keySet());
//
find lead's related records
String
q = 'Select '
+ sFieldLead + ', '
+ sFieldContact + ' From '
+ s + ' Where '
+ sFieldLead + ' in :setIdLeads';
for(sObject
sobj : database.query(q)){
Id
idLead = Id.valueOf(String.valueof(sobj.get(sFieldLead)));
Id
idContact = mapConvertedContactByLead.get(idLead);
sobj.put(sFieldContact,
idContact);
lstObjUpdate.add(sobj);
}
}
}
Auszug aus der Testklasse:
static
testMethod
void
myUnitTest() {
//
Create Test Data
createTestData();
//-------------------
Test.startTest();
//
CONVERT LEAD
Database.Leadconvert
lc = new
Database.Leadconvert();
lc.setLeadId(l.id);
LeadStatus
convertStatus = [select
id,MasterLabel from
LeadStatus
where
isConverted=true
limit
1];
lc.setConvertedStatus(convertStatus.MasterLabel);
Database.LeadConvertResult
lcr = Database.convertLead(lc);
Test.stopTest();
//
Check Lead
Lead
lCheck = [Select
Id, ConvertedContactId from
Lead where
Id =:l.id];
//
Check related objects
Unterobjekt1 check1 = [Select Contact__c from Unterobjekt1 where Lead__c =:l.id];
Unterobjekt2 check2 = [Select Name__c from Unterobjekt2 where Lead__c =:l.id];
system.assertNotEquals(null,
lCheck.ConvertedContactId);
system.assertEquals(lCheck.ConvertedContactId, check1.Contact__c);
system.assertEquals(lCheck.ConvertedContactId, check2.Name__c);
}
Kommentare
Kommentar veröffentlichen