Salesforce
The topic which i am covering here to show the PDF on apex
page, this is very simple but the main thing over here is that i need to fetch
the data from SAP system through Boomi and than after it takes the data from
Boomi in Salesforce than it would show as PDF. So first i am showing my apex
page code here. The reason being I am using dynamic rendering is that if there
would be no data to show than it should show the blank white page with appropriate
message, if I would not use the condition than if it would not contain any data
than it is showing blank BLACK pdf style without data.
<apex:page controller="GenerateInvoicePdf"
sidebar="false">
<apex:pageMessages />
<script>
var isPDF =
'{!bJSEnable}';
if
(isPDF=='true')
{
window.location.href =
"data:application/pdf;base64,{!sData}";
}
</script>
</apex:page>
|
I am showing you the controller of this page, in this
controller, I using HTTP call to pass the request envelop from Salesforce to
Boomi (Integration tool) and get the response envelope from Boomi to saleforce.
This below function returns HTTPResponse. First it is getting Endpoint from
custom lable.
public static HttpResponse getInfoBoomi()
{
// Get the
Endpoint URL from custom label
String
EndPointUrl = Label.CGI_Invoice_Pdf_Boomi_Endpoint_Url;
Httprequest
request=new Httprequest();
request.setmethod('POST');
request.setTimeout(120000);
request.setEndpoint(EndPointUrl);
//set the
request string for Boomi service connector containing Invoice No which will
than pass to SAP to get the Invoice Base64 code
string strInput='<?xml
version="1.0" encoding="UTF-8"?>' +
'<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
' <soapenv:Body> <setOutput
xmlns="https://secure.logmeinrescue.com/API/API.asmx">
<eOutput>XML</eOutput></setOutput>' +
' <notifications
xmlns="http://soap.sforce.com/2005/09/outbound">' +
' <Notification> ' +
' <InvoceId>'+
ApexPages.currentPage().getParameters().get(CGIConstant.Invoice_PDF_Query_String)
+'</InvoceId>' +
' </Notification>' +
' </notifications>' +
' </soapenv:Body>' +
'</soapenv:Envelope>';
//replace
all & with & to avoid xml encoding issue
strInput=strInput.replaceAll('&','&');
request.setBody(strInput);
Http
httprequest=new Http();
string
responseMessage;
//send http
request to boomi process
res=httprequest.send(request);
return res;
}
|
The value of Label.CGI_Invoice_Pdf_Boomi_Endpoint_Url = https://test.connect.boomi.com/ ws/simple/getInvoice; boomi_auth=dGhlY2hhbWJlcmxhaW5ncm91cGluYy1US1pBRDY=. If you noticed that this contains service URL coming from Boomi Web service server operation URL path, see the below image red block, the operation also contains Request profile as well as response profile. Request profile contains the HTTP request envelope coming from Salesforce which is yellow highlighted area in above table. This request receive by Boomi through the below operation. Now the after Simple URL path in above Endpoint URL we need to put “;boomi_auth=” and after that it needs the Account Id and Token concatenate by Colon (:) and then user should convert the whole string into base64 like in our case the Account Id is “TestAccount” and Token is “HGFTH76-JGBVFF876-KJKBV23”. This account info can be get from Boomi Atom Management under Shared Web Server settings. So after getting this information, we need to concatenate both the things and put colon in between them like TestAccount: HGFTH76-JGBVFF876-KJKBV23 than convert this string into the base 64 and then put that encoded value after boomi_auth in above URL. If you wee in above source code it is passing Invoice Id from apex controller to Boomi using Http request envelop and that Invoice Id is fetching from query string.
FIGURE
1
FIGURE
2
On first step, I am using the Web Service Server connector
which receive data from Salesforce and as you already seen its operation in
figure 1. This operation has request and response part. Request XML contains
the same XML meta data schema as Request envelope which I covered in first
table containing yellow highlighted area. Response would be contains those XML
tags which your SAP system would return. So you can make your response after
seeing the response from SAP. In above figure 2, in map part I am mapping the
request Invoice Id to SAP request profile, see the below image
FIGURE
3
For
SAP, I have used the BAPI, and consuming the BAPI which contains Request and
Response profile.
FIGURE
4
The
important thing here is that how to return the response envelop from Boomi to
Salesforce so I have used the Return Document, which actually returns the
response to that source which actually send the request. I also wanted to cover
the message properties. I am using the service response envelope message into
the message node in which I am passing the whole encoded base 64 Invoice PDF
from SAP in between the Ack tag please see the below image.
Actually
I have a Generate Invoice button in Invoice detail page which open this above
apex page as a pop passing Invoice Number and this Invoice Number than passed
to the SAP through Boomi. So when user click this button and get the proper response
than we get the status code 200 which is Http success response. There are few
more generic responses which might user get, so developer should maintain the
proper error handling for end user. I am pasting the whole controller code here
which will guide you through the end.
public
with sharing class GenerateInvoicePdf{
transient Blob bString;
public Boolean bJSEnable {get; set;}
public static HttpResponse getInfoBoomi()
{
// Get the Endpoint URL from custom
label
String EndPointUrl =
Label.CGI_Invoice_Pdf_Boomi_Endpoint_Url;
Httprequest request=new
Httprequest();
request.setmethod('POST');
request.setTimeout(120000);
request.setEndpoint(EndPointUrl);
//set the request string for Boomi
service connector containing Invoice No which will than pass to SAP to get
the Invoice Base64 code
string strInput='<?xml
version="1.0" encoding="UTF-8"?>' +
'<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
' <soapenv:Body> <setOutput
xmlns="https://secure.logmeinrescue.com/API/API.asmx">
<eOutput>XML</eOutput></setOutput>' +
' <notifications
xmlns="http://soap.sforce.com/2005/09/outbound">' +
' <Notification> ' +
' <InvoceId>'+
ApexPages.currentPage().getParameters().get(CGIConstant.Invoice_PDF_Query_String)
+'</InvoceId>' +
' </Notification>' +
' </notifications>' +
' </soapenv:Body>' +
'</soapenv:Envelope>';
//replace all & with &
to avoid xml encoding issue
strInput=strInput.replaceAll('&','&');
request.setBody(strInput);
Http httprequest=new Http();
string responseMessage;
HttpResponse res;
//send http request to boomi process
res=httprequest.send(request);
return res;
}
public void Initializedata()
{
HttpResponse res = getInfoBoomi();
sData = res.getbody();
Boolean result =
String.isEmpty(sData);
string extraNodes = '';
if (res.getStatusCode() ==
integer.valueof(Label.HTTP_SUCCESS_REQUEST))
{
if
(sData.contains(CGIConstant.HTTP_Boomi_Response_Ack_Having_Null)|| sData ==
'')
{
bJSEnable = false;
ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.WARNING ,Label.ERR_INV_DOESNOT_EXISTS));
}
else
{
if
((sData.IndexOf(CGIConstant.HTTP_Boomi_Response_Ack_Start_Tag) < 0) &&
(sData.IndexOf(CGIConstant.HTTP_Boomi_Response_Ack_End_Tag) < 0))
{
bJSEnable = false;
ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.WARNING ,Label.ERR_INV_DOESNOT_EXISTS));
}
sData =
sData.substring(sData.IndexOf(CGIConstant.HTTP_Boomi_Response_Ack_Start_Tag)
+ 5);
extraNodes =
sData.Substring(sData.IndexOf(CGIConstant.HTTP_Boomi_Response_Ack_End_Tag));
sData =sData.replace(extraNodes
,'');
}
}
else if(res.getStatusCode() ==
integer.valueof(Label.ERR_HTTP_BAD_REQUEST))
ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.WARNING ,
Label.ERR_HTTP_BAD_REQUEST_MESSAGE));
else if(res.getStatusCode() ==
integer.valueof(Label.ERR_HTTP_UNAUTHORIZE_REQUEST))
ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.WARNING ,
Label.ERR_HTTP_UNAUTHORIZE_REQUEST_MESSAGE));
ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.WARNING ,
Label.ERR_HTTP_NOT_FOUND_REQUEST_MESSAGE));
else if(res.getStatusCode() ==
integer.valueof(Label.ERR_HTTP_INTERNAL_REQUEST))
ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.WARNING ,
Label.ERR_HTTP_INTERNAL_REQUEST_MESSAGE));
else if(res.getStatusCode() ==
integer.valueof(Label.ERR_HTTP_UNAVAILABLE_REQUEST))
ApexPages.addMessage(new
ApexPages.Message(ApexPages.Severity.WARNING ,
Label.ERR_HTTP_UNAVAILABLE_REQUEST_MESSAGE));
}
public GenerateInvoicePdf()
{
bJSEnable = true;
Initializedata();
}
}
|
In
above code if you see, I have covered all the Http request and show them as proper
message for the user.
No comments:
Post a Comment