• Rameshvar Dayal 48
  • NEWBIE
  • 4 Points
  • Member since 2021

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 3
    Replies
I am having an error in 7 challenge.User-added image

My Trigger code is:

trigger ProjectTrigger on Project__c (after update) {
    //after trigger to fire if the Status is set to Billable.
    If (Trigger.isAfter && Trigger.isUpdate){
        for(Project__c proj : Trigger.new){
            if(proj.Status__c.equals('Billable')){
                BillingCalloutService.callBillingService(proj.ProjectRef__c, proj.Billable_Amount__c);
            }
        }
    }
}


My BillingCalloutService class is as follows:

public class BillingCalloutService {
               
    //method to run asynchronously or in future, invoked from trigger.
    @future(callout=true)
    public static void callBillingService(String projectRef, Decimal billingAmount){
        //gets the custom settings values.
        ServiceCredentials__c servCred = ServiceCredentials__c.getValues('BillingServiceCredential');
        //creating the project object to be passed in argument below.
        BillingServiceProxy.project project = new BillingServiceProxy.project();
        project.username = servCred.Username__c;
        project.password = servCred.Password__c;
        project.projectid = projectRef;
        project.billAmount = billingAmount;
                                //synchronous call to the Billing Invoice system.
        BillingServiceProxy.InvoicesPortSoap11 invoiceCall = new BillingServiceProxy.InvoicesPortSoap11();
        //getting the response back from billing system.
        String response = invoiceCall.billProject(project);
                                //if the response is ok, need to change the billing status to 'Billed'
        List<Project__c> proj;
        if (response != null && response.equalsIgnoreCase('OK')){
            proj = [SELECT Status__c FROM Project__c WHERE ProjectRef__c =: projectRef];
            if(proj.size() > 0){
                proj[0].Status__c = 'Billed';
            }
            update proj;
        }
    }
}

BillingServiceProxy:

//Generated by wsdl2apex

public class BillingServiceProxy {
    public class billProjectRequest_element {
        public BillingServiceProxy.project project;
        private String[] project_type_info = new String[]{'project','http://salesforce.com/th/invoice-web-service',null,'1','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/th/invoice-web-service','true','false'};
        private String[] field_order_type_info = new String[]{'project'};
    }
    public class project {
        public String username;
        public String password;
        public String projectid;
        public Double billAmount;
        private String[] username_type_info = new String[]{'username','http://salesforce.com/th/invoice-web-service',null,'1','1','false'};
        private String[] password_type_info = new String[]{'password','http://salesforce.com/th/invoice-web-service',null,'1','1','false'};
        private String[] projectid_type_info = new String[]{'projectid','http://salesforce.com/th/invoice-web-service',null,'1','1','false'};
        private String[] billAmount_type_info = new String[]{'billAmount','http://salesforce.com/th/invoice-web-service',null,'1','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/th/invoice-web-service','true','false'};
        private String[] field_order_type_info = new String[]{'username','password','projectid','billAmount'};
    }
    public class billProjectResponse_element {
        public String status;
        private String[] status_type_info = new String[]{'status','http://salesforce.com/th/invoice-web-service',null,'1','1','false'};
        private String[] apex_schema_type_info = new String[]{'http://salesforce.com/th/invoice-web-service','true','false'};
        private String[] field_order_type_info = new String[]{'status'};
    }
    public class InvoicesPortSoap11 {
        public String endpoint_x = 'http://sb-integration-bs.herokuapp.com:80/ws';
        public Map<String,String> inputHttpHeaders_x;
        public Map<String,String> outputHttpHeaders_x;
        public String clientCertName_x;
        public String clientCert_x;
        public String clientCertPasswd_x;
        public Integer timeout_x;
        private String[] ns_map_type_info = new String[]{'http://salesforce.com/th/invoice-web-service', 'BillingServiceProxy'};
        public String billProject(BillingServiceProxy.project project) {
            BillingServiceProxy.billProjectRequest_element request_x = new BillingServiceProxy.billProjectRequest_element();
            request_x.project = project;
            BillingServiceProxy.billProjectResponse_element response_x;
            Map<String, BillingServiceProxy.billProjectResponse_element> response_map_x = new Map<String, BillingServiceProxy.billProjectResponse_element>();
            response_map_x.put('response_x', response_x);
            WebServiceCallout.invoke(
              this,
              request_x,
              response_map_x,
              new String[]{endpoint_x,
              '',
              'http://salesforce.com/th/invoice-web-service',
              'billProjectRequest',
              'http://salesforce.com/th/invoice-web-service',
              'billProjectResponse',
              'BillingServiceProxy.billProjectResponse_element'}
            );
            response_x = response_map_x.get('response_x');
            return response_x.status;
        }
    }
}



Please help me to kick off this error.Thanks in advance
I store the accessToken and refresh token so I can refresh it at some point in the future when the access token is no longer valid.  However, it seems that the refresh token would expired at some point or get invalidated automatically.  Can someone explain the lifetime of a refresh token?

in Digging_Deeper_into_OAuth_2.0_on_Force.com (https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com).  It is mentioned that it is only revoked by the user:
The refresh token represents the user's authorization to the application, and is valid until explicitly revoked by the user, via My Settings ➤ Personal ➤ Advanced User Details ➤ OAuth Connected Apps.
However, there is an edit in the same doc that mentiones that refresh token also have an expiration time:

The refresh token may have an indefinite lifetime, persisting for an admin-configured interval or until explicitly revoked by the end-user. The client application can store the refresh token, using it to periodically obtain fresh access tokens, but should be careful to protect it against unauthorized access, since, like a password, it can be repeatedly used to gain access to the resource server.
Since refresh tokens may expire or be revoked by the user outside the control of the client application, the client must handle failure to obtain an access token, typically by replaying the protocol from the start.