Ein Kunde nutzt den Standard Approval Process von Salesforce im Vertriebsprozess.
Bearbeiter versenden viele Angebote mit vielen Positionen.
Wer mit Approvals gearbeitet hat, weiss, dass die Approval-Maske ganz simpel aussieht. Das Layout lässt sich nicht bearbeiten.
Der Kunde möchte aber eine Übersicht aller Produkte aus dem jeweiligen Angebot sowie den Approval Status dieser Produkte sehen.
Salesforce bietet leider keine Möglichkeit, weder den Approval Process noch dessen Layout zu überschreiben.
Lösung: mit einem unschönen, aber funktionierenden Hack lässt sich die Anforderung umsetzen:
wir überschreiben die Standard Approval Process URL:
Standard URL: /p/process/ProcessInstanceWorkitemWizardStageManager
mit einer anderen URL mittels JavaScript. Diese neue URL verlinkt auf eine VisualForce Page:
Ersetzten durch URL: /apex/QuoteApprovalProcess
Die Standard Approval URLs können sowohl auf der Homepage als auch im Kontext erscheinen.
Daher brauchen wir eine zentrale Lösung, die immer greift.
Dazu wird eine neue Homepage Komponente erstellt: Custom Approval Process.
Diese Komponente muss auf der Navigationsseite (links) erscheinen, und vom Typ "HTML" sein.
Die implementierte JavaScript Funktion ersetzt alle Standard Approval URLs durch eine neue URL mit der Referenz auf eine VisualForce Seite.
Nach der Übernahme der neuen Komponente in das Homepage Layout,
erscheint diese im Frontend, auf der Navigationsleiste ganz unten.
Ein weiterer, aber zu vernachlässigender Nachteil dieser Lösung ist die Ausführung der JavaScript Funktion bei jeder Seitenaktualisierung. Da JavaScript lokal ausgeführt wird, und die Funktion "nur" URLs ersetzt, ist keine Performancebeeinträchtigung zu spüren.
Jetzt muss nur noch eine auf die Kundenwünsche zugeschnittene VisualForce Seite gebaut werden.
Eine neue VisualForce Seite:
Wie kriegt der Controller mit, um welchen Approval Process es sich handelt?
Ganz einfach! Mit JavaScript ersetzen wir nur einen Teil der Standard Approval URLs. Jede URL enthält einen Parameter - ID. Das ist die ID des jeweiligen Prozess-Datensatzes.
Über diese ID (genannt processId ) findet der Controller das aktuelle Angebot und dessen einzelnen Positionen.
Bearbeiter versenden viele Angebote mit vielen Positionen.
Wer mit Approvals gearbeitet hat, weiss, dass die Approval-Maske ganz simpel aussieht. Das Layout lässt sich nicht bearbeiten.
Der Kunde möchte aber eine Übersicht aller Produkte aus dem jeweiligen Angebot sowie den Approval Status dieser Produkte sehen.
Salesforce bietet leider keine Möglichkeit, weder den Approval Process noch dessen Layout zu überschreiben.
Lösung: mit einem unschönen, aber funktionierenden Hack lässt sich die Anforderung umsetzen:
wir überschreiben die Standard Approval Process URL:
Standard URL: /p/process/ProcessInstanceWorkitemWizardStageManager
mit einer anderen URL mittels JavaScript. Diese neue URL verlinkt auf eine VisualForce Page:
Ersetzten durch URL: /apex/QuoteApprovalProcess
Die Standard Approval URLs können sowohl auf der Homepage als auch im Kontext erscheinen.
Daher brauchen wir eine zentrale Lösung, die immer greift.
Dazu wird eine neue Homepage Komponente erstellt: Custom Approval Process.
Diese Komponente muss auf der Navigationsseite (links) erscheinen, und vom Typ "HTML" sein.
Die implementierte JavaScript Funktion ersetzt alle Standard Approval URLs durch eine neue URL mit der Referenz auf eine VisualForce Seite.
<script>
window.onload=customApprovalProcess;
function customApprovalProcess(){
var
allHrefs = document.getElementsByTagName("a");
var
strSearch = "/p/process/ProcessInstanceWorkitemWizardStageManager";
var
strReplace = "/apex/QuoteApprovalProcess";
for
(var i=0; i< allHrefs.length; i++) {
var
str = allHrefs[i].href;
allHrefs[i].href
= str.replace(strSearch, strReplace);
}
}
</script>
Nach der Übernahme der neuen Komponente in das Homepage Layout,
erscheint diese im Frontend, auf der Navigationsleiste ganz unten.
Ein weiterer, aber zu vernachlässigender Nachteil dieser Lösung ist die Ausführung der JavaScript Funktion bei jeder Seitenaktualisierung. Da JavaScript lokal ausgeführt wird, und die Funktion "nur" URLs ersetzt, ist keine Performancebeeinträchtigung zu spüren.
Jetzt muss nur noch eine auf die Kundenwünsche zugeschnittene VisualForce Seite gebaut werden.
Eine neue VisualForce Seite:
<apex:page
controller="QuoteApporvalProcessController">
<apex:pagemessages
></apex:pagemessages>
<apex:sectionHeader
title="{!$Label.ApprovalRequest}"/>
<apex:form
>
<apex:pageBlock
title="{!$Label.QAProcess_BlockTitle}">
<!--
BUTTONS -->
<!--
++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<apex:pageBlockButtons
location="bottom">
<apex:commandButton
value="Approve"
action="{!approve}"/>
<apex:commandButton
value="Reject"
action="{!reject}"/>
<apex:commandButton
value="Cancel"
action="{!cancel}"/>
</apex:pageBlockButtons>
<!--
FORM -->
<!--
++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<apex:pageBlockSection
columns="1">
Darstellung der Felder aus dem Angebot
</apex:pageBlockSection>
</apex:pageBlock>
<!--
TABLE WITH PRODUCTS (POSITION LINE ITEMS) -->
<!--
++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<apex:pageBlock
title="{!$Label.QAProcess_BlockTitleProducts}">
Darstellung einzelner Positionen aus dem Angebot
</apex:pageBlock>
</apex:form>
<!--
Approvals related list -->
<!--
+++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
Darstellung des aktuellen Approval Status aller Produkte aus dem Angebot
<apex:relatedList
subject="{!quote}"
list="ProcessSteps"
/>
</apex:page>
Wie kriegt der Controller mit, um welchen Approval Process es sich handelt?
Ganz einfach! Mit JavaScript ersetzen wir nur einen Teil der Standard Approval URLs. Jede URL enthält einen Parameter - ID. Das ist die ID des jeweiligen Prozess-Datensatzes.
Über diese ID (genannt processId ) findet der Controller das aktuelle Angebot und dessen einzelnen Positionen.
public
without
sharing
class
QuoteApporvalProcessController {
public
Quote__c
quote {get;
set;}
public
PageReference redirectPage;
public
String processId;
public
String quoteId;
//
CONSTRUCTOR
public
QuoteApporvalProcessController(){
Prozess ID ist als Parameter verfügbar
processId
= ApexPages.currentPage().getParameters().get('id');
//
get quote id from the Process Instance
if(processId
!= ''){
ProcessInstanceWorkitem
piw = [select
Id,
ProcessInstanceId,
IsDeleted,
p.ProcessInstance.TargetObjectId
from ProcessInstanceWorkitem
p
where p.id=: processId Limit 1];
if(piw
!= null){
quoteId
= piw.ProcessInstance.TargetObjectId;
// OBJECT: Quote with POSITION
LINE ITEMS
if(quoteId
!= ''){
quote = [select
Name,
(Select
Id,
Name,
from
Positionen__r)
from
Quote__c
where
id = :quoteId];
redirectPage = new
PageReference('/'+
quoteId);
}
}
}
}
Funktionalität der einzelnen Buttons: Approve, Reject, Cancel.
//BUTTON
APPROVE
public
PageReference Approve(){
Approval.ProcessWorkitemRequest
req = new
Approval.ProcessWorkitemRequest();
req.setComments(quote.QAProcess_Comments__c);
req.setAction('Approve');
req.setWorkitemId(processId);
Approval.ProcessResult
result = Approval.process(req);
System.assert(result.isSuccess());
return
redirectPage;
}
//BUTTON
REJECT
public
PageReference Reject(){
Approval.ProcessWorkitemRequest
req = new
Approval.ProcessWorkitemRequest();
req.setComments(quote.QAProcess_Comments__c);
req.setAction('Reject');
req.setWorkitemId(processId);
Approval.ProcessResult
result = Approval.process(req);
return
redirectPage;
}
//BUTTON
CANCEL
public
PageReference Cancel(){
return
redirectPage ;
}
}
-------------------------------------------------------------------------------
Einige Ideen während der Umsetzung habe ich aus dem Blog Running Apex Code in a Standard Approval Process übernommen: http://comitydesigns.com/blog/running-apex-code-in-a-standard-approval-process/
-------------------------------------------------------------------------------
Einige Ideen während der Umsetzung habe ich aus dem Blog Running Apex Code in a Standard Approval Process übernommen: http://comitydesigns.com/blog/running-apex-code-in-a-standard-approval-process/
Kommentare
Kommentar veröffentlichen