Beim Entwickeln und Testen einer neuen Funktionalität für Portal Benutzer, die Cases einstellen dürfen, bin ich auf ein interessantes Systemverhalten gestossen.
Kurze Beschreibung:
ein Portal Benutzer erstellt einen neuen Case. Das Feld "Account" bleibt leer, bzw. dieses Feld hat die Eigenschaft "Read only" für Portal Benutzer und ist somit nicht editierbar.
Nach dem Speichern und dem erneuten Öffnen des Cases ist das Feld "Account" gefüllt.
Recherche:
ich war mir ziemlich sicher, dass hier ein Trigger im Spiel ist. Nachdem ich die Ressourcen untersucht habe, stellte ich fest, dass es keine programmierte Funktion gibt, die den Account berechnet und im Case abspeichert.
Nach einigen Tests, unter anderem mit der neu entwickelten Funktion, war das Muster erkennbar:
* ein Portal Benutzer impliziert die Existenz der beiden Datensätze "Contact" und "User" im System
* ein Contact ist zwangsweise mit einem Account verknüpft
=> der mit dem Contact verknüpfte Account wird bei der Neuanlage von Cases automatisch vom System im Case abgelegt, falls das Account-Feld leer ist.
Hier noch eine kurze Beschreibung inklusive Lösung der oben erwähnten Funktion.
Aufgabe: das Feld "Asset" stellt die mit dem Account verknüpften Assets dar. Da das Account Feld bei der Neuanlage leer ist, ist die Asset-Auswahl nicht möglich.
Ziel: Asset-Auswahl muss bei der Neuanlage ermöglicht werden.
Lösung: ein neuer Button "New Portal Case" ruft eine VisualForce Page auf. Der Controller der VisualForce Page führt eine Aktion aus. Diese Aktion erstellt einen neuen Case mit dem für den Portal User relevanten Account und öffnent den neuen Case im Bearbeitungsmodus.
(Der Nachteil dieser Lösung: der neue Case wird immer in die Datenbank geschrieben)
Der New Case Button
ruft die VisualForce Page auf
================== TEST ============================
Kurze Beschreibung:
ein Portal Benutzer erstellt einen neuen Case. Das Feld "Account" bleibt leer, bzw. dieses Feld hat die Eigenschaft "Read only" für Portal Benutzer und ist somit nicht editierbar.
Nach dem Speichern und dem erneuten Öffnen des Cases ist das Feld "Account" gefüllt.
Recherche:
ich war mir ziemlich sicher, dass hier ein Trigger im Spiel ist. Nachdem ich die Ressourcen untersucht habe, stellte ich fest, dass es keine programmierte Funktion gibt, die den Account berechnet und im Case abspeichert.
Nach einigen Tests, unter anderem mit der neu entwickelten Funktion, war das Muster erkennbar:
* ein Portal Benutzer impliziert die Existenz der beiden Datensätze "Contact" und "User" im System
* ein Contact ist zwangsweise mit einem Account verknüpft
=> der mit dem Contact verknüpfte Account wird bei der Neuanlage von Cases automatisch vom System im Case abgelegt, falls das Account-Feld leer ist.
Hier noch eine kurze Beschreibung inklusive Lösung der oben erwähnten Funktion.
Aufgabe: das Feld "Asset" stellt die mit dem Account verknüpften Assets dar. Da das Account Feld bei der Neuanlage leer ist, ist die Asset-Auswahl nicht möglich.
Ziel: Asset-Auswahl muss bei der Neuanlage ermöglicht werden.
Lösung: ein neuer Button "New Portal Case" ruft eine VisualForce Page auf. Der Controller der VisualForce Page führt eine Aktion aus. Diese Aktion erstellt einen neuen Case mit dem für den Portal User relevanten Account und öffnent den neuen Case im Bearbeitungsmodus.
(Der Nachteil dieser Lösung: der neue Case wird immer in die Datenbank geschrieben)
Der New Case Button
ruft die VisualForce Page auf
<apex:page
controller="SF42_Portal_NewCase"
action="{!newPortalCase}"
>
<apex:form
>
<apex:pageBlock
>
<apex:pageMessages
/>
</apex:pageBlock>
</apex:form>
</apex:page>
, welche die Action newPortalCase ausführt
public
without
sharing
class
SF42_Portal_NewCase {
public
string accountID;
public
Case
newCase;
/*
CONSTRUCTOR */
/********************/
public
SF42_Portal_NewCase(){
accountID
= searchDependingAccount(userinfo.getuserid(), false);
}
/*
newPortalCase() *******/
/*************************/
public
pageReference newPortalCase(){
PageReference
pageRef;
if(isValidId(accountID)
== true){
//
ACCOUNT was found
//
create new case with account
newCase
= createCase(accountID);
}else{
//
ACCOUNT is not found
//
create new case without account
newCase
= createCase(null);
}
//
Write new case into the database and open it in edit mode
try{
insert
newCase;
pageRef
= new
pagereference('/'
+ newCase.id + '/e');
pageRef.setRedirect(true);
}catch
(exception e){ ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage())); }
return
pageRef;
}
/*
createCase() *******/
/*************************/
private
Case
createCase(String accountID){
Case
c = new
Case();
//
write fields
if(accountID
!= null)
c.AccountId
= accountID;
return
c;
}
/*
isValidId() *******/
/*************************/
private
boolean isValidId(String sid){
Boolean
isId = true;
Id
validId;
try{
validId
= (ID) sid;
}catch
(Exception e){
isId
= false;
}
return
isId;
}
/*
searchDependingAccount()
*******/
/*************************/
private
string searchDependingAccount(ID UserID, boolean onlyContactID){
User
u = [Select
u.Contact.AccountId,
u.ContactId,IsPortalEnabled From
User u
where
ID = :UserID];
if(u.IsPortalEnabled){
if(onlyContactID)
return
u.ContactId;
if(u.Contact.AccountId
!= NULL){
return
u.Contact.AccountId;
}else{
return
'PortalWithoutContact';
}
}else{
return
'';
}
}
}
================== TEST ============================
@isTest
private
class
SF42_Test_Portal_NewCase {
static
Profile p;
static
Account a;
static
Contact c;
static
User u;
static
testMethod
void
testNewPortalCaseWithValidAccount() {
createTestData();
system.runas(u){
Test.startTest();
//
we have no cases
list<Case>
lstCases = new
list<Case>([Select
id from
case
where
ContactId =:c.Id]);
system.assertEquals(true,
lstCases.isEmpty());
//
Create a new case
Pagereference
pageRef = Page.SF42_Portal_NewCase;
SF42_Portal_NewCase
controller = new
SF42_Portal_NewCase();
controller.newPortalCase();
//
we must have 1 case
list<Case>
lstCasesCheck = new
list<Case>([Select
id, accountId from
case
where
ContactId =:c.Id]);
system.assertEquals(1,
lstCasesCheck.Size());
system.assertEquals(a.id,
lstCasesCheck[0].AccountId);
Test.stopTest();
}
}
static
testMethod
void
testNewPortalCaseWithInvalidAccount() {
createTestData();
system.runas(u){
Test.startTest();
//
Create a new case
Pagereference
pageRef = Page.SF42_Portal_NewCase;
SF42_Portal_NewCase
controller = new
SF42_Portal_NewCase();
//
override the account id with invalid string
controller.accountID
= 'invalidAccountID';
//
we have no cases
list<Case>
lstCases = new
list<Case>([Select
id, AccountID from
case
where
ContactId =:c.Id]);
system.assertEquals(true,
lstCases.isEmpty());
//*********
Create New Case ***************
controller.newPortalCase();
//*****************************************
system.assertequals(null,
controller.newCase.AccountId);
//
we must have 1 case
list<Case>
lstCasesCheck = new
list<Case>([Select
id, AccountID from
case
where
ContactId =:c.Id]);
system.assertEquals(1,
lstCasesCheck.Size());
Test.stopTest();
}
}
public
static
void
createTestData(){
p
= [Select
id from
Profile
where
name = 'CSR Portal USER'
limit
1];
system.assertnotequals(null,
p);
a
= TestDataGenerator.createTestAccount(1, true);
c
= TestDataGenerator.createTestContact(1, a.id, true);
u
= TestDataGenerator.createTestUser(1, p.id, false);
u.ContactId
= c.Id;
insert
u;
system.assertnotequals(null,
u);
System.assert([select
isPortalEnabled from
user where
id = :u.id].isPortalEnabled, 'User was
not flagged as portal enabled.');
}
}
================= Class TestDataGenerator =================
public
with
sharing
class
TestDataGenerator{
//
Account
public
static
Account
createTestAccount(Integer i, Boolean insertObject)
{
Account
acc = new
Account();
acc.Name
= 'TestAccount'
+ i;
if(insertObject)
insert
acc;
return
acc;
}
//
Contact
public
static
Contact
createTestContact(Integer i, Id accId, Boolean insertObject)
{
Contact
con = new
Contact();
con.FirstName
= 'Test';
con.LastName
= 'Contact'
+ i;
con.AccountId
= accId;
con.Email
= con.LastName + '@'
+ accId + '.com';
if(insertObject)
insert
con;
return
con;
}
//User
public
static
User
createTestUser(Integer i, Id profileId, Boolean insertObject){
User
u = new
User();
u.ProfileId
= profileId;
u.FirstName
= 'Firstname';
u.LastName
= 'User' +
i;
u.Username
= 'test@user'
+ i + '.de';
u.Email
= 'test@user'
+ i + '.de';
u.Alias
= 'u' + i;
u.CommunityNickname
= 'test@user'
+ i + '.de';
u.TimeZoneSidKey
= 'America/Los_Angeles';
u.LocaleSidKey
= 'en_US';
u.EmailEncodingKey
= 'ISO-8859-1';
u.LanguageLocaleKey
= 'en_US';
u.IsActive
= true;
if(insertObject)
insert
u;
return
u;
}
}
Kommentare
Kommentar veröffentlichen