• Melissa Mueller 9
  • NEWBIE
  • 20 Points
  • Member since 2017

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 4
    Questions
  • 7
    Replies
I have asked this question on salesforce.stackexchange.com approximately 10 days ago. I received some feedback and edited my code. I still can't get error messages to display and controller no longer calls my apex code! Could someone, anyone, look over the updated code and see if you can tell why this is happeninig or how I can fix it? I would really appreciate the help! The question is here:  https://salesforce.stackexchange.com/questions/192422/i-am-seeing-the-visualforce-page-message-in-my-debug-logs-but-cannot-get-it-to-d
I am trying to create an approval history report and have followed the basic instructions in this post: Create approval history report with object fields?

I am now onto getting the information from an approval process instance and am stuck because I cannot get the instance to create any NewWorkItems. I have followed the process found here: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_process_example.htm

I have also noticed that my getActorIds() returns null and the getInstanceStatus() returns Approved which it absolutely should not.
Any ideas on why this is happening would be greatly appreciated.

Apex Class:
global class GetQuoteAndApprovalProcessIds {
@InvocableMethod(label='Get Quote And Approval Ids')
global static List<Id> getIds(List<Id> quoteIdList){
    Id quoteId = quoteIdList[0];
    System.debug('!!!!!!quoteId!!!!!' + quoteId);
    List<Id> quoteAndApprovalProcessIds = new List<Id>();
    Id actorId;
    Id originalActorId;
    Id processInstanceId;

    ProcessInstance instance = [SELECT Id FROM ProcessInstance WHERE TargetObjectId =: quoteId Limit 1];
    System.debug('!!!!!!instance.Id!!!!!' + instance.Id);

    ProcessInstance step = [SELECT CompletedDate, CreatedById, CreatedDate,Id,IsDeleted,LastActorId,LastModifiedById,LastModifiedDate,
                                ProcessDefinitionId,Status,SubmittedById,SystemModstamp,TargetObjectId, (SELECT ID, ProcessNodeId, StepStatus,
                                                                                                         Comments,TargetObjectId,ActorId,CreatedById,
                                                                                                         IsDeleted,IsPending,OriginalActorId,ProcessInstanceId,
                                                                                                         RemindersSent,CreatedDate 
                                                                                                         FROM StepsAndWorkitems ) 
                                FROM ProcessInstance WHERE ProcessInstance.Id =: instance.Id];
    System.debug('!!!!!!ProcessInstanceStep!!!!!' + step);
    return quoteAndApprovalProcessIds;
}   

global class QuoteAndApprovalIdResults {
    @InvocableVariable
    global Id quoteId;
    @InvocableVariable
    global List<Id> approvalProcessIds = new List<Id>();
}   
}

Apex Test Class:
@isTest(seeAllData = true)
public class GetQuoteAndApprovalProcessIds_Test {
static testMethod void testQuoteApprovalReportingObject(){
    // Commercial Sales Manager Joe Vincenti
    Id userId = '005i0000004yabM';
    User u = new User();
    u.Id = userId;
    // Using record types of commercial no pm
    Id recordTypeQuoteId = '01231000000y0r3';
    Id recordTypeProjectId = '01231000000y0qv';
    date projectCloseDate = date.parse('09/21/2018');
    Id priceBookId = '01s0Z000004H39F';

    System.runAs(u){
        Opportunity project = new Opportunity(name='Quote Reporting Test Project', CloseDate=projectCloseDate, StageName = 'Bid', Probability=70, Project_State__c='GA', Construction_Type__c='Retrofit', Competitors1__c='LG', Type='OEM', Federal_Government_Project__c='No', RecordTypeId=recordTypeProjectId);
        insert project;
        System.debug('!!!!!!project!!!!!' + project);

        SBQQ__Quote__c quote = new SBQQ__Quote__c(SBQQ__Status__c='New', Include_in_Forecasting__c='No', SBQQ__Opportunity2__c=project.Id, Approval_Justification__c='Facing strong competition from LG.', RecordTypeId=recordTypeQuoteId, SBQQ__PricebookId__c=priceBookId);
        insert quote;
        System.debug('!!!!!!quote!!!!!' + quote);

        List<Product2> productsList = [select Id, productCode, isActive, Product_Family__c, substitution_Product_code__c, Other_Category__c, Spec_Product__c, 
                                       Product_Bundle__c from Product2 where productCode = 'AE-201'];
        System.debug('!!!!!!productsList!!!!!!' + productsList);

        List<SBQQ__QuoteLine__c> quoteLines = new List<SBQQ__QuoteLine__c>();
        quoteLines.add(new SBQQ__QuoteLine__c(SBQQ__Quantity__c = 1, SBQQ__Product__c = productsList[0].Id, SBQQ__Quote__c = quote.Id, Multiplier__c = 0.1));

        insert quoteLines;
        System.debug('!!!!!!quoteLines!!!!!' + quoteLines);    

    // Create an approval request for the account
    Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest();
    req1.setComments('Submitting request for approval.');
    req1.setObjectId(quote.id);

    // Submit on behalf of a specific submitter
    req1.setSubmitterId(u.Id); 

    // Submit the record to specific process and skip the criteria evaluation
    req1.setProcessDefinitionNameOrId('Commercial_Sales_Manager_Approval');
    req1.setSkipEntryCriteria(true);
    System.debug('!!!!!!req1!!!!!' + req1);

    // Submit the approval request for the account
    Approval.ProcessResult result = Approval.process(req1);
    // Verify the result
    System.assert(result.isSuccess());
    System.debug('!!!!!!result!!!!!' + result);

    // Approve the submitted request
    // First, get the ID of the newly created item
    List<Id> newWorkItemIds = result.getNewWorkitemIds();
    System.debug('!!!!!!newWorkItemIds!!!!!' + newWorkItemIds);

    // Instantiate the new ProcessWorkitemRequest object and populate it
    Approval.ProcessWorkitemRequest req2 = new Approval.ProcessWorkitemRequest();
    req2.setComments('Rejecting request. Discount to high! Please adjust by -5%.');
    req2.setAction('Rejected');

    // Use the ID from the newly created item to specify the item to be worked
    req2.setWorkitemId(newWorkItemIds.get(0));

    // Submit the request for approval
    Approval.ProcessResult result2 =  Approval.process(req2);

    ApexPages.currentPage().getParameters().put('Id', quote.Id);
    System.debug('*******ApexPages.currentPage().getParameters().get()*******' +      ApexPages.currentPage().getParameters().get('id'));
    Id quoteId = ApexPages.currentPage().getParameters().get('id');
    List<Id> quoteIdList = new List<Id>();
    quoteIdList.add(quoteId);            
    GetQuoteAndApprovalProcessIds.getIds(quoteIdList);
    } 
}
}

Debug Log (relevant output only due to this working with the Steel Brick managed package, there are tons of irrelevant lines): 

Project (AKA Opportunity) is created:

15:11:17.1 (493292522)|USER_DEBUG|[21]|DEBUG|!!!!!!project!!!!!Opportunity:{Name=Quote Reporting Test Project, CloseDate=2018-09-21 00:00:00, StageName=Bid, Probability=70, Project_State__c=GA, Construction_Type__c=Retrofit, Competitors1__c=LG, Type=OEM, Federal_Government_Project__c=No, RecordTypeId=01231000000y0qvAAA, Id=006e000000E9KqHAAV}

Steel Brick CPQ Quote and ProductList created:
15:11:18.87 (1322517172)|USER_DEBUG|[26]|DEBUG|!!!!!!quote!!!!!SBQQ__Quote__c:{SBQQ__Status__c=New, Include_in_Forecasting__c=No, SBQQ__Opportunity2__c=006e000000E9KqHAAV, Approval_Justification__c=Facing strong competition from LG., RecordTypeId=01231000000y0r3AAA, SBQQ__PricebookId__c=01s0Z000004H39FQAS, Id=a0Ue0000008h29HEAQ}
15:11:18.87 (1329296217)|USER_DEBUG|[30]|DEBUG|!!!!!!productsList!!!!!!(Product2:{Id=01t31000007kX7uAAE, ProductCode=AE-201, IsActive=true, Product_Family__c=PSG, Other_Category__c=5, Product_Bundle__c=false})

Quote Lines added and Approval.ProcessSubmitRequest created:
15:11:19.618 (3353871002)|USER_DEBUG|[36]|DEBUG|!!!!!!quoteLines!!!!!(SBQQ__QuoteLine__c:{SBQQ__Quantity__c=1, SBQQ__Product__c=01t31000007kX7uAAE, SBQQ__Quote__c=a0Ue0000008h29HEAQ, Multiplier__c=0.1, Id=a0Qe0000008rWDtEAM})
15:11:19.618 (3354137090)|USER_DEBUG|[54]|DEBUG|!!!!!!req1!!!!!Approval.ProcessSubmitRequest[getObjectId=a0Ue0000008h29HEAQ;getProcessDefinitionNameOrId=Commercial_Sales_Manager_Approval;getSkipEntryCriteria=true;getSubmitterId=005i0000004yabMAAQ;]

The result of submitting the process request and the lines that follow it to the end of the debug file:
15:11:20.623 (3624353425)|USER_DEBUG|[60]|DEBUG|!!!!!!result!!!!!Approval.ProcessResult[getActorIds=null;getEntityId=a0Ue0000008h29HEAQ;getErrors=null;getInstanceId=04ge000000173YgAAI;getInstanceStatus=Approved;getNewWorkitemIds=();isSuccess=true;]
15:11:20.623 (3624460915)|USER_DEBUG|[65]|DEBUG|!!!!!!newWorkItemIds!!!!!()
15:11:20.623 (3630604821)|FATAL_ERROR|System.ListException: List index out of bounds: 0

Class.GetQuoteAndApprovalProcessIds_Test.testQuoteApprovalReportingObject: line 74, column 1
15:11:20.623 (3630619052)|FATAL_ERROR|System.ListException: List index out of bounds: 0

Class.GetQuoteAndApprovalProcessIds_Test.testQuoteApprovalReportingObject: line 74, column 1
15:11:20.623 (3630636277)|CODE_UNIT_FINISHED|GetQuoteAndApprovalProcessIds_Test.testQuoteApprovalReportingObject
15:11:20.623 (3631347772)|EXECUTION_FINISHED
 
In the following code I get the error: 'Variable does not exist: synchedDates'
From what I am seeing, the list variable synchedDates is initialized and not out of scope. This error occurs in both the Salesforce Developer Console as well as Oracle. 

Even crazier, the first time I refer to that list variable is NOT where the error is being thrown! The error occurs on the first System.debug call on the second IF statement!

It is giving me a headache trying to figure out what could possibly be wrong! PLEASE HELP!!!! 
List<SBQQ__Quote__c> synchedDates =
[Select Id, PSG_Project_Synched__c, StageName__c
From SBQQ__Quote__c
Where QuoteID__c = :psgMasterQuoteToReset[0].PSG_Master_Quote__c 
];
if (synchedDates[0].PSG_Project_Synched__c != null){
System.debug('************The Quote Synch Date Before Assigning Null Was: ' + synchedDates[0].PSG_Project_Synched__c);
synchedDates[0].PSG_Project_Synched__c = null;
System.debug('********Quote Synch Date is now: ' + synchedDates[0].PSG_Project_Synched__c );
}
if (synchedDates[0].StageName__c != 'Bid'){
System.debug('************The Quote Stage Name Before Assigning Bid Was:' + synchedDates[0].PSG_Project_Synched__c);
synchedDates[0].StageName__c = 'Bid';
System.debug('************Quote Stage Name is now: ' + synchedDates[0].StageName__c);
}

 
Trigger name exists on different SObject type: Quote
I had a trigger that I initially wanted to work just before a Quote is saved, but we decided to move the trigger to the Opportunity object instead of the quote. I had originally set it up like this:
trigger PSGProjectDeleteTrigger on Quote (before update) {
    for(Quote quoteSelected : Trigger.new){ CODE TO COMPLETE WHEN TRIGGER FIRES }
I was able to save the trigger like that, but when I went back to it and changed it to :
trigger PSGProjectDeleteTrigger on Opportunity (before update) {
    for(Opportunity projectSelected : Trigger.new){ CODE TO COMPLETE WHEN TRIGGER FIRES }
I receive the following error:
Error: Compile Error: Trigger name exists on different SObject type: Quote at line 1 column 1

I found a post about this that suggested not using the developer console and instead going to setup>develop>apex triggers and editing it their directly. I did that and still receive the same error.

Another post suggested that I chang the name of the trigger so I added the number two to the end of the trigger name and still receive the same error.

Both Quote and Opportunity are standard objects so I am sure there is no problem with the object names.

Any ideas?????



 
I have asked this question on salesforce.stackexchange.com approximately 10 days ago. I received some feedback and edited my code. I still can't get error messages to display and controller no longer calls my apex code! Could someone, anyone, look over the updated code and see if you can tell why this is happeninig or how I can fix it? I would really appreciate the help! The question is here:  https://salesforce.stackexchange.com/questions/192422/i-am-seeing-the-visualforce-page-message-in-my-debug-logs-but-cannot-get-it-to-d
In the following code I get the error: 'Variable does not exist: synchedDates'
From what I am seeing, the list variable synchedDates is initialized and not out of scope. This error occurs in both the Salesforce Developer Console as well as Oracle. 

Even crazier, the first time I refer to that list variable is NOT where the error is being thrown! The error occurs on the first System.debug call on the second IF statement!

It is giving me a headache trying to figure out what could possibly be wrong! PLEASE HELP!!!! 
List<SBQQ__Quote__c> synchedDates =
[Select Id, PSG_Project_Synched__c, StageName__c
From SBQQ__Quote__c
Where QuoteID__c = :psgMasterQuoteToReset[0].PSG_Master_Quote__c 
];
if (synchedDates[0].PSG_Project_Synched__c != null){
System.debug('************The Quote Synch Date Before Assigning Null Was: ' + synchedDates[0].PSG_Project_Synched__c);
synchedDates[0].PSG_Project_Synched__c = null;
System.debug('********Quote Synch Date is now: ' + synchedDates[0].PSG_Project_Synched__c );
}
if (synchedDates[0].StageName__c != 'Bid'){
System.debug('************The Quote Stage Name Before Assigning Bid Was:' + synchedDates[0].PSG_Project_Synched__c);
synchedDates[0].StageName__c = 'Bid';
System.debug('************Quote Stage Name is now: ' + synchedDates[0].StageName__c);
}

 
Trigger name exists on different SObject type: Quote
I had a trigger that I initially wanted to work just before a Quote is saved, but we decided to move the trigger to the Opportunity object instead of the quote. I had originally set it up like this:
trigger PSGProjectDeleteTrigger on Quote (before update) {
    for(Quote quoteSelected : Trigger.new){ CODE TO COMPLETE WHEN TRIGGER FIRES }
I was able to save the trigger like that, but when I went back to it and changed it to :
trigger PSGProjectDeleteTrigger on Opportunity (before update) {
    for(Opportunity projectSelected : Trigger.new){ CODE TO COMPLETE WHEN TRIGGER FIRES }
I receive the following error:
Error: Compile Error: Trigger name exists on different SObject type: Quote at line 1 column 1

I found a post about this that suggested not using the developer console and instead going to setup>develop>apex triggers and editing it their directly. I did that and still receive the same error.

Another post suggested that I chang the name of the trigger so I added the number two to the end of the trigger name and still receive the same error.

Both Quote and Opportunity are standard objects so I am sure there is no problem with the object names.

Any ideas?????



 
I'm passing this challenge, however when I actually test it out by clicking on an account in the account list item, I get this exception: 

"Something has gone wrong. Action failed: c$AccountMap$controller$accountSelected [TypeError: Cannot read property 'reuseTiles' of undefined] Failing descriptor: {c$AccountMap$controller$accountSelected}."

I did some debugging and found that the location and latitude of the account are indeed being capture by my event, so it looks like this might be a problem with the leaflet function map.panTo(). Does anyone know the solution to this issue? Here's my code, although it's exactly the same as the tutorial's.
 
({
    jsLoaded: function(component, event, helper) {

        setTimeout(function() {
            var map = L.map('map', {zoomControl: false}).setView([37.784173, -122.401557], 14);
            L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
                {
                    attribution: 'Tiles © Esri'
                }).addTo(map);
            component.set("v.map", map);
        });
    },

    accountsLoaded: function(component, event, helper) {

        // Add markers
        var map = component.get('v.map');
        var accounts = event.getParam('accounts');
        for (var i=0; i<accounts.length; i++) {
            var account = accounts[i];
            var latLng = [account.Location__Latitude__s, account.Location__Longitude__s];
            L.marker(latLng, {account: account}).addTo(map);
        }  
    },

    accountSelected: function(component, event, helper) {
        // Center the map on the account selected in the list
        var map = component.get('v.map');
        var account = event.getParam("account");
        alert(account.Location__Latitude__s + ', ' + account.Location__Longitude__s);
        map.panTo([account.Location__Latitude__s, account.Location__Longitude__s]);
    }
})

 

I'm testing a trigger on our Opportunities which kick off an Approval Process when the Opportunity's Process_Stage__c field changes. If I create an Opportunity and move it between stages through the UI I can see the ProcessInstance, ProcessInstanceStep and ProcessInstanceWorkitem are all created. I'm using Force.com Explorer Beta and have verified this. So far so good.

 

In my test class I'm creating an Opportunity and inserting it, then updating the Process_Stage__c. After the update I'm seeing the ProcessInstance and ProcessInstanceStep are being created but there are no ProcessInstanceWorkitems at all in the database. I want to test rejecting and approving the Approval but without the ProcessInstanceWorkitem I can't do this (as far as I understand the Approval Process).

 

Below is my code, there are a few lines where I've tried various ways to retrieve the ProcessInstanceWorkitems, finally resulting in [SELECT ActorId, CreatedById, Id FROM ProcessInstanceWorkitem]; because up until this point I thought my SOQL was wrong, now I don't think the ProcessInstanceWorkitems are being created for some reason. Is there something fundamental I'm missing? Should this be possible to do from a unit test?

 

// Yadda yadda yadda Create Opportunity (o) here
		insert(o); 
		
        // Make sure this isn't already queued up for approval before saving as a Stage 2
		List<ProcessInstance> processInstances = [select Id, Status from ProcessInstance where TargetObjectId = :o.id];
		System.assertEquals(processInstances.size(),0,'Approval Process already triggered when saving at Stage 1');

		o.Process_Stage__c = TestConstants.STAGE_2; 
		update(o);

        // Assert an approval process has been initiated
		processInstances = [select Id, Status from ProcessInstance where TargetObjectId = :o.id];
		System.assertEquals(processInstances.size(),1, 'Only 1 approval processes should be created when saving at Stage 2, found '+processInstances.size());
		
		List<ProcessInstanceStep> processInstanceSteps = [SELECT ActorId, OriginalActorId, StepStatus 
			FROM ProcessInstanceStep 
			WHERE ProcessInstanceId = :processInstances[0].id];
        System.assert(processInstanceSteps.size() > 0,'No approval processes steps found when saving at Stage 2');

        List<ProcessInstanceWorkitem> processInstanceWorkitems = [SELECT ActorId, CreatedById, Id FROM ProcessInstanceWorkitem]; // WHERE ProcessInstanceId = :processInstances[0].id];
        //List<ProcessInstanceWorkitem> processInstanceWorkitems = [Select p.Id from ProcessInstanceWorkitem p where p.ProcessInstance.TargetObjectId = :o.id];
        //List<ProcessInstance> processInstancesWithWorkitems = [SELECT Id, (SELECT Id, ActorId, ProcessInstanceId FROM Workitems) FROM ProcessInstance WHERE TargetObjectId = :o.id];
		System.assert(processInstanceWorkitems.size() > 0,'No approval processes Workitems found when saving at Stage 2');
 
  • October 04, 2013
  • Like
  • 2