Find your content:

Search form

You are here

Getting remaining licenses of customer portal using apex

 
Share

When a new portal user is created, can we check the number of used and total portal licenses?


Attribution to: doga

Possible Suggestion/Solution #1

There are UsedLicenses / TotalLicenses fields from UserLicense object available only through API call and only available for organization subscribed for related Pilot Program.

If your question relates to usage of UsedLicenses / TotalLicenses fields, you may vote up for this idea https://success.salesforce.com/ideaView?id=08730000000cJTEAA2 and also you may be interested in a managed beta package I created recently which may serve as workaround for this. It screenscrapes company profile page and gets number of total license.

This package includes a User_License_Extended__c custom object which contains Total License number and Used Licenses number ( and some more fields ), these numbers are updated whenever a user is activated or deactivated or user profile is changed assuming package is properly set up with necessary data

Install link for production-like org https://login.salesforce.com/packaging/installPackage.apexp?p0=04t580000001ENa

More details and release notes https://patlatus.wordpress.com/2016/03/07/salesforce-uletas-beta-1-0-release-notes/

Just noticed Bob was giving more advanced approach than I had implemented, using

> PageReference pr=new PageReference('/'+orgId); String
> rawData=pr.getContent().toString();

instead of doing callout - I should try that as well and rewrite my package - didn't know that pr.getContent() may be used for screen scraping


Attribution to: Patlatus

Possible Suggestion/Solution #2

THe only way I've been able to achieve this kind of functionality in apex is via screen scraping. Create a pagereference to the company information page, execute the getcontent method to retrieve the raw HTML and then find the table row(s) containing the portal license information and extract the relevant elements. Its fragile, as there's no guarantee that the format of this page will remain the same (though it has for the last couple of years I've been using this technique) and you also can't execute the getContent from a trigger or scheduled apex, so I've tied it to a visualforce page embedded into a dashboard.

You can access the page via the organization id, so the code to get the content is:

Organization orgDetails =[select Id from Organization 
                      limit 1];
Id orgId = orgDetails.Id;
PageReference pr=new PageReference('/'+orgId);
String rawData=pr.getContent().toString();

and then you can locate a particular element using code similar to the following, which extracts the percentage of data space currently used::

Integer pos=rawData.indexOf('Used Data Space');
String result;
if (-1!=pos)
{
   pos=rawData.indexOf('<td', pos);
   if (-1!=pos)
   {
      pos=rawData.indexOf('>', pos+3);
      if (-1!=pos)
      { 
         Integer endPos=rawData.indexOf('%)', pos);
         result=rawData.substring(pos+1, endPos+2);
      }
   }
}

Attribution to: Bob Buzzard

Possible Suggestion/Solution #3

The technique above worked great for me. I used it in a Schedulable interface as triggers can't employ the getContent method. We just run this nightly. Below is the code I used to implement in our Org:

global class LicenseAvail implements Schedulable {

public String result;
public String orgName;
public String orgCountry;

global void execute(SchedulableContext ctx){

 //Get Organization to get content of company info details
         Organization orgDetails =[ select Id, Name, Country from Organization limit 1];
            Id orgId = orgDetails.Id;
            orgName = orgDetails.Name;
            orgCountry = orgDetails.Country;

        PageReference pr=new PageReference('/'+orgId);
        //called screenscraping: get the data from the page
        String rawData=pr.getContent().toString();

    //locate a particular element within the raw data
    //the info after this line contains the active license count
    String licRow = '>Salesforce</th><td class=" dataCell  ">Active</td><td class=" dataCell  numericalColumn">';
    Integer licLen = licRow.length();
    System.debug('******************** licLen: ' + licLen);
    Integer pos=rawData.indexOf(licRow);

if (-1!=pos)
{
         Integer licStart = pos + licLen;
         result=rawData.substring(licStart, licStart+3);
         System.debug('***************** SubString: ' + result);
  }

//get used licenses and determine if count of available is 5 or less

Decimal lic = decimal.valueOf(result);

integer u = [select count() from user where profile.UserLicense.Name = 'salesforce' and isactive = true];

 Decimal userCount = decimal.valueOf(u);

Integer totalUnused = (lic.intValue() - userCount.intValue());
System.debug('************ Licenses???? ***************** ' + String.valueOf(totalUnused));
    if(totalUnused <= 5) {

   System.debug('Sending Email...');
   Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
   String[] toAdd = new String[]{'email@address.com'};
   mail.setToAddresses(toAdd);
   mail.setReplyTo('email@address.com');
   mail.setSenderDisplayName('Salesforce License Notification');
   mail.setSubject(orgName + ' License Count: ' + String.valueOf(totalUnused));
   mail.setBccSender(false);
   mail.setUseSignature(false);
   mail.setPlainTextBody('License Count: ' + String.valueOf(totalUnused));
   mail.setHtmlBody('License Availability Alert:<br/>' + orgName + ', '+ orgCountry + '<br/>' + 'License Count: ' + String.valueOf(totalUnused));
   List<Messaging.SendEmailResult> results = Messaging.sendEmail(new Messaging.Email[] { mail });
   System.debug('****************** Email Sent: '+results.get(0).isSuccess() );
}

}   
}

Attribution to: EvaD
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/3916

My Block Status

My Block Content