• jd_labbe
  • NEWBIE
  • 0 Points
  • Member since 2010

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 10
    Questions
  • 10
    Replies

Hello,

 

I am interested in looking for a SW developer with Salesforce.com and BigMachines experience. Any ideas on where I can find someone?

Hello,

 

I need to find an easy way to provide a filtered look-up list to en end user when relating to another object. I have 2 custom child objects on the opportunity object named "Enhancement Request" and "Feature Commitment", respectively. User creates Enhancement requests which are automatically associated with the opportunity. A 3rd custom object named "Feature" would eventually get associated with the "Enhancement Request". "Feature Commitment" is simply an object that links Opportunity to Feature. When creating a "Feature Commitment", the lookup field to "Features" pulls entire list of Features in the table. What I would like to do is create a filtered look-up page that only provides Features associated with the "Enhancement Requests" related on that particular opportunity record. Any tips would be appreciated.

Hello,

 

We had a vendor write an Apex class that takes a string sent from BigMachines (quoting tool) to SF.com and compiles it into data sent to a custom object. This class works in production. However, we are attempting to deploy 2 triggers from sandbox to production and now receiving the following error:

 

Failure Message: System Limitation too many future calls 11 Failure Stack Trace: "Class.BigMachinesSyncBOMClass.syncQuoteBOMWithOpty: line 5, column10 Trigger.syncBOMTrigger: line 54, column 9"

 

SF.com developer support provided the following input, but I have no idea how to do this:

 

 

The error you are getting about ' Too many future calls' in the Apex class 'BigMachinesSyncBOMClass' due to the method updateBOMLater within the method 'syncQuoteBOMWithOpty'.

 

It is coming due to there is a governor limit of a maximum of 10 asynchronous calls within the context of a single Apex logical transaction. You are hitting this limit because it is calling the method more than ten times.

 

Total number of methods with the future annotation allowed per Apex invocation = 10

 

Below mentioned is the helpful link to know more about it:

 

http://www.salesforce.com/us/developer/docs/apexcode/index_CSH.htm#apex_gov_limits.htm?SearchType=Stem

 

To avoid this governor limit, you can incorporate batch apex in your implementation.Each iteration of the batch resets the limit, so pass the limitation you want to process into the batch.

 

 

Apex Code is below:

 

public class BigMachinesSyncBOMClass {
    public static void syncQuoteBOMWithOpty(ID quoteId, ID opportunityId, String BOM, Boolean delOldBOMs) {
         updateBOMLater(quoteId, opportunityId, BOM, delOldBOMs);
    }
    
    
    private static BOM_Line_Item__c[] getOldOpportunityBOM(ID opportunityId) {
        return [select Id, Opportunity__c from BOM_Line_Item__c
                where Opportunity__c = :opportunityId];       
    }
    
    private static BOM_Line_Item__c[] getNewOpportunityBOM(ID quoteId, ID opportunityId, String BOM) {
        List<BOM_Line_Item__c> oppBOMToCreate = new List<BOM_Line_Item__c>();
        
        //String BOM = 'N-GEO-01-00250%%3%%1%%family%%line%%model%%configuration%%12345&N-GEO-01-00251%%3%%1%%family%%line%%model%%configuration%%12346&';
        
        /* Parse BOM String
         *  '&'     -   splits lines
         *  '%%'    -   splits attributes
         */
        String[] BOMArr = BOM.split('&');
        List<String> BOMCodes = new List<String>();
        Map<String, String> BOMProdMap = new Map<String,String>();
        //Only run if BOM is not empty
        if (BOMArr.size() > 0 && BOM != 'empty') {
            //Create Map of BOM line string to SFDC Product2 object
            for (Integer i=0; i<BOMArr.size(); i++){
                String productCodeStr = BOMArr[i].substring(0,BOMArr[i].indexOf('%'));
                BOMCodes.add(productCodeStr);
            }
        
            Product2[] BOMProds = [select Id, ProductCode from Product2 where ProductCode in :BOMCodes];
        
            for (Integer i=0; i<BOMProds.size(); i++) {
                BOMProdMap.put(BOMProds[i].ProductCode,BOMProds[i].Id);
            }
            
             //Create BOM_Line_Item object list for each line
            //loop through BOMProds, get line string from Map
            for (Integer i=0; i<BOMArr.size(); i++){
                //split line to get attributes
                String[] BOMAttributes = BOMArr[i].split('%%'); 
                
                //Create now BOM_Line_Item object and add it to List
                oppBOMToCreate.add(
                    new BOM_Line_Item__c(   
                            Product_Code__c = BOMAttributes[0], 
                            Quantity__c = integer.valueOf(BOMAttributes[1]), 
                            Document_Number__c = BOMAttributes[2], 
                            Product_Family__c = BOMAttributes[3],
                            Product_Line__c = BOMAttributes[4],
                            Product_Model__c =BOMAttributes[5],
                            Configuration_Name__c = BOMAttributes[6],
                            //Serial_Number__c =BOMAttributes[7],
                            Opportunity__c = opportunityId,
                            Product__c = BOMProdMap.get(BOMAttributes[0])
                    )
                );
            }
            
        }
        //Return BOM list
        return oppBOMToCreate;
    }
    @future private static void updateBOMLater(ID quoteId, ID opportunityId, String BOM, Boolean delOldBOMs) {
     
        if(delOldBOMS){
            BOM_Line_Item__c[] oppBOMToDelete = getOldOpportunityBOM(opportunityId);
            delete oppBOMToDelete;
        }
        
        if(BOM != '' && BOM != 'empty' && BOM != 'noBOM' && BOM != ''){
            BOM_Line_Item__c[] oppBOMToInsert = getNewOpportunityBOM(quoteId, opportunityId, BOM);
            insert oppBOMToInsert;
        }
    }
    public class QuoteSyncException extends Exception {}    
    
    static testMethod void testSyncQuoteWithOpty() {
        Opportunity opty = new Opportunity();
        opty.Name = 'BigMachines test opportunity';
        opty.StageName = 'Prospecting';
        opty.CloseDate = Date.today();
        insert opty;
        // BigMachines__Quote__c.ensurePrimary - begin test
        BigMachines__Quote__c[] quotes = new BigMachines__Quote__c[3];
        for (Integer i=0; i<quotes.size(); i++) {
            quotes[i] = new BigMachines__Quote__c();
            quotes[i].Name = 'BigMachines test quote ' + (i+1);
            quotes[i].BigMachines__Opportunity__c = opty.Id;
            //quotes[i].Stage__c = 'Prospecting';
            quotes[i].BOM__c = '850010100%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&696-0024-04-002%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&850010100%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&696-0024-04-002%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&';
            quotes[i].BOM2__c = '850010100%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&696-0024-04-002%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&850010100%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&696-0024-04-002%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&';
            quotes[i].BOM3__c = '850010100%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&696-0024-04-002%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&850010100%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&696-0024-04-002%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&';
            quotes[i].BOM4__c = '850010100%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&696-0024-04-002%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&850010100%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&696-0024-04-002%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&';
            quotes[i].BOM5__c = '850010100%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&696-0024-04-002%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&850010100%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&696-0024-04-002%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&';
            
        }
        insert quotes;  
        // BigMachines__Quote__c.ensurePrimary - end test
        
        
    
        quotes[0].BigMachines__Is_Primary__c = true;
        update quotes; 
        quotes[0].BigMachines__Is_Primary__c = false;
        quotes[1].BigMachines__Is_Primary__c = true;
        update quotes; 
        
                
        
        updateBOMLater(quotes[1].id, opty.id, quotes[1].BOM__c,true);
        // BigMachinesSyncBOMClass.syncQuoteWithOpty - end positive test
    } 
}

 

I have just been asked by management to explore options managing one master opportunity comprised by group of individual opportunities. Today we are managing this individually and currently have no way to tie them together to represent the one opportunity.

 

I am looking for a way to:

  • Create one master opportunity 
  • Batch create child opportunity records (designated number) 
  • Roll-up the $ amount of child opportunity records to the $ amount of the master opportunity
  • Forecast/Report on the master opportunity to reflect open vs. closed as each individual opportunity is closed

Note: We utilize BigMachines for quoting

 

Use case:

 

There is one big project for Acme Telecom that's worth $1M. This is captured in SF.com as 1 opportunity for $1M. This customer has asked that we break out the project in 10 phases and provide 1 quote for each phase. Since we could only have 1 primary quote per opportunity, we would have to create 10 separate opportunities worth $100K per quote. 

 

However, our sales management would like to report/forecast the 1 opportunity. As each quote is booked, the respective opportunity would be closed in SF.com and reflected in the forecasts and reporting. Ultimately, we would end up with $1M of closed opportunities over the course of the FY. 

 

This is scenario starting to occur more frequently and it is becoming a nightmare to manage.  

 

Any ideas?

I am interested in utilizing chatter similar to the email notification workflow for a custom object named Support Request. FYI, the "Support Request" SR record is similar to an IT help ticket, but for the business. If an account manager needed assistance with an RFP response, then he would create a new SR and assign it to the appropriate RFP writer. What I would like to do is utilize Chatter to send the alert to the assignee similar to email notification via workflow.

 

Use case:

 

  • Account Manager Dan Taylor creates SR for RFP request. Account Manager's primary proposal writer is Nancy Brown. 
  • Once the new SR is saved, a chatter feed associated with the SR, but sent from Dan Taylor would be sent to Nancy Brown (@Nancy Brown) providing some of the information from the SR such as Name, Description, Account and Due Date. 
  • This would allow bi-directional communication between Account Manager and Nancy through email via this chatter feed.

 

Why?

 

Our goal here would be to simplify the process of capturing the dialogue between SR creator and assignee via simple email exchange, in the SR's Chatter feed without requiring the assignee to initially have to log into SF.com to enter their response. 

 

The @username feature on an object in Chatter is very powerful because it allows the receiver to simply reply to the email notification from their email as opposed to having to click on the link, log into SF.com and enter the response. 

 

 

Has anyone been able to figure this out? If so, your assistance would be appreciated.

 

Thanks!!

 Hello,

 

I'm about to pull my hair out here trying to unit test this trigger in order to move it to production. This passes all of my manual use case testing, but I only get 72% code coverage with the apex class unit testing. Not sure what's happening here. Any assistance would be appreciated.

 

Code is provided below, but the following lines are highlighted in red on the test debug:

 

createdsr.add(new Service_Request__c (Opportunity__c = o.Id, Account__c=o.AccountID, Name = o.Name, Service_Group__c = 'RFx'));

 

 

system.debug(Ex);

 

 

Apex Trigger Code:

 

trigger AutomateCreateDSR on Opportunity (after insert,after update) {
List<Service_Request__c> createdsr = new List <Service_Request__c> {};
List<Id> oppIds = new List<Id>{};

for (opportunity o : trigger.new) {
oppIds.add(o.id);

{
List<Service_Request__c> dsr= [SELECT Id,Opportunity__c,Account__c,Name,Service_Group__c FROM Service_Request__c WHERE Opportunity__c IN :oppIds];
if (dsr.size()==0 && o.Point_by_Point_Response__c ==True)
{
createdsr.add(new Service_Request__c (Opportunity__c = o.Id, Account__c=o.AccountID, Name = o.Name, Service_Group__c = 'RFx'));
}

try {
insert createdsr;
}
catch (Exception Ex)
{
system.debug(Ex);
}
}
}
}
 
 
 
 

 

Apex Class Test Code:

 

@isTest
private class TestAutomateDSR {

   private static Opportunity opportunity1;
    
    static {
        
        opportunity1 = new Opportunity();
        opportunity1.Name = 'TestOpp1';
        opportunity1.StageName = '1-Targeted';
        opportunity1.CloseDate = Date.valueOf('2011-09-01');
        opportunity1.Amount = 200;
        //opportunity1.Has_Orders__c = false;

        insert opportunity1;            
    }
        
    static testMethod void testhasDSRs() {
    List<Service_Request__c> createdsr = new List <Service_Request__c> {};
   
    createdsr.add(new Service_Request__c (Opportunity__c = opportunity1.Id, Account__c=opportunity1.AccountID, Name = opportunity1.Name, Service_Group__c = 'RFx'));  
            
      try {
  insert createdsr;
   }
  catch (Exception Ex)
  {
  system.debug(Ex);
   }
   }
   }
 

 

Hello,

 

I am a newbie to Apex code development and would like  to write a trigger that will change the forecastcategoryname on an opportunity to 'Omitted' if the Account custom field named "Validation Status" = 'Test Account'. This means that the trigger would have to look up the Validation Status value on the Account associated with the opportunity. Can someone please advise me on how to best achieve this?

 

Thanks!!

Hello,

 

I am a newbie to apex coding, but trying to figure out a way to override the opportunity amount once opportunity products have been added. Through research, I was able to write a trigger that allows my sales reps to override the amount on an opportunity with Opportunity products. BTW, we utilize BigMachines for quoting, so the opportunity products are sync'd over from BigMachines each time the quote is updated. 

 

As I mentioned before, this solution works, but in order to remove the override flag and revert back to the quote amount, the salesrep must go back into BigMachines and re-save the quote record to initiate the product update thus updating the amount. What I would like to do is figure out a way to insert logic in the For statement that will either replace the Unit Price with "RealAmount" if the override flag = true  OR utilize Unit Price if override flag is not True.

 

Any ideas? Trigger code is below:

 

 

 

trigger OverrideLISalesPrice2 on Opportunity (after insert,after update) {
List<Id> oppIds = new List<Id>{};

for (Opportunity o : Trigger.new)

{
if (o.Use_Actual_Amount__c == True && o.HasOpportunityLineItem == true)
    oppIds.add(o.id);
}

 List<OpportunityLineItem> theLines = [SELECT Id,UnitPrice,RealAmount__c FROM OpportunityLineItem WHERE OpportunityId IN :oppIds];
 
   
    for(OpportunityLineItem OLI : theLines)  
                    {  
                        OLI.UnitPrice = OLI.RealAmount__c;  
                    }  
                update theLines;

 

Hello,

 

I just started testing this plug-in last week and loved the flexibility. I just created 2 custom fields in the Account Object, but was unable to pull the 2 fields with a query. Any idea why custom fields are not brought into the query? I am using Office 2007 and everything else seems to work fine.

 

Thanks!!

Hello,

 

We had a vendor write an Apex class that takes a string sent from BigMachines (quoting tool) to SF.com and compiles it into data sent to a custom object. This class works in production. However, we are attempting to deploy 2 triggers from sandbox to production and now receiving the following error:

 

Failure Message: System Limitation too many future calls 11 Failure Stack Trace: "Class.BigMachinesSyncBOMClass.syncQuoteBOMWithOpty: line 5, column10 Trigger.syncBOMTrigger: line 54, column 9"

 

SF.com developer support provided the following input, but I have no idea how to do this:

 

 

The error you are getting about ' Too many future calls' in the Apex class 'BigMachinesSyncBOMClass' due to the method updateBOMLater within the method 'syncQuoteBOMWithOpty'.

 

It is coming due to there is a governor limit of a maximum of 10 asynchronous calls within the context of a single Apex logical transaction. You are hitting this limit because it is calling the method more than ten times.

 

Total number of methods with the future annotation allowed per Apex invocation = 10

 

Below mentioned is the helpful link to know more about it:

 

http://www.salesforce.com/us/developer/docs/apexcode/index_CSH.htm#apex_gov_limits.htm?SearchType=Stem

 

To avoid this governor limit, you can incorporate batch apex in your implementation.Each iteration of the batch resets the limit, so pass the limitation you want to process into the batch.

 

 

Apex Code is below:

 

public class BigMachinesSyncBOMClass {
    public static void syncQuoteBOMWithOpty(ID quoteId, ID opportunityId, String BOM, Boolean delOldBOMs) {
         updateBOMLater(quoteId, opportunityId, BOM, delOldBOMs);
    }
    
    
    private static BOM_Line_Item__c[] getOldOpportunityBOM(ID opportunityId) {
        return [select Id, Opportunity__c from BOM_Line_Item__c
                where Opportunity__c = :opportunityId];       
    }
    
    private static BOM_Line_Item__c[] getNewOpportunityBOM(ID quoteId, ID opportunityId, String BOM) {
        List<BOM_Line_Item__c> oppBOMToCreate = new List<BOM_Line_Item__c>();
        
        //String BOM = 'N-GEO-01-00250%%3%%1%%family%%line%%model%%configuration%%12345&N-GEO-01-00251%%3%%1%%family%%line%%model%%configuration%%12346&';
        
        /* Parse BOM String
         *  '&'     -   splits lines
         *  '%%'    -   splits attributes
         */
        String[] BOMArr = BOM.split('&');
        List<String> BOMCodes = new List<String>();
        Map<String, String> BOMProdMap = new Map<String,String>();
        //Only run if BOM is not empty
        if (BOMArr.size() > 0 && BOM != 'empty') {
            //Create Map of BOM line string to SFDC Product2 object
            for (Integer i=0; i<BOMArr.size(); i++){
                String productCodeStr = BOMArr[i].substring(0,BOMArr[i].indexOf('%'));
                BOMCodes.add(productCodeStr);
            }
        
            Product2[] BOMProds = [select Id, ProductCode from Product2 where ProductCode in :BOMCodes];
        
            for (Integer i=0; i<BOMProds.size(); i++) {
                BOMProdMap.put(BOMProds[i].ProductCode,BOMProds[i].Id);
            }
            
             //Create BOM_Line_Item object list for each line
            //loop through BOMProds, get line string from Map
            for (Integer i=0; i<BOMArr.size(); i++){
                //split line to get attributes
                String[] BOMAttributes = BOMArr[i].split('%%'); 
                
                //Create now BOM_Line_Item object and add it to List
                oppBOMToCreate.add(
                    new BOM_Line_Item__c(   
                            Product_Code__c = BOMAttributes[0], 
                            Quantity__c = integer.valueOf(BOMAttributes[1]), 
                            Document_Number__c = BOMAttributes[2], 
                            Product_Family__c = BOMAttributes[3],
                            Product_Line__c = BOMAttributes[4],
                            Product_Model__c =BOMAttributes[5],
                            Configuration_Name__c = BOMAttributes[6],
                            //Serial_Number__c =BOMAttributes[7],
                            Opportunity__c = opportunityId,
                            Product__c = BOMProdMap.get(BOMAttributes[0])
                    )
                );
            }
            
        }
        //Return BOM list
        return oppBOMToCreate;
    }
    @future private static void updateBOMLater(ID quoteId, ID opportunityId, String BOM, Boolean delOldBOMs) {
     
        if(delOldBOMS){
            BOM_Line_Item__c[] oppBOMToDelete = getOldOpportunityBOM(opportunityId);
            delete oppBOMToDelete;
        }
        
        if(BOM != '' && BOM != 'empty' && BOM != 'noBOM' && BOM != ''){
            BOM_Line_Item__c[] oppBOMToInsert = getNewOpportunityBOM(quoteId, opportunityId, BOM);
            insert oppBOMToInsert;
        }
    }
    public class QuoteSyncException extends Exception {}    
    
    static testMethod void testSyncQuoteWithOpty() {
        Opportunity opty = new Opportunity();
        opty.Name = 'BigMachines test opportunity';
        opty.StageName = 'Prospecting';
        opty.CloseDate = Date.today();
        insert opty;
        // BigMachines__Quote__c.ensurePrimary - begin test
        BigMachines__Quote__c[] quotes = new BigMachines__Quote__c[3];
        for (Integer i=0; i<quotes.size(); i++) {
            quotes[i] = new BigMachines__Quote__c();
            quotes[i].Name = 'BigMachines test quote ' + (i+1);
            quotes[i].BigMachines__Opportunity__c = opty.Id;
            //quotes[i].Stage__c = 'Prospecting';
            quotes[i].BOM__c = '850010100%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&696-0024-04-002%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&850010100%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&696-0024-04-002%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&';
            quotes[i].BOM2__c = '850010100%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&696-0024-04-002%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&850010100%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&696-0024-04-002%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&';
            quotes[i].BOM3__c = '850010100%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&696-0024-04-002%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&850010100%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&696-0024-04-002%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&';
            quotes[i].BOM4__c = '850010100%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&696-0024-04-002%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&850010100%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&696-0024-04-002%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&';
            quotes[i].BOM5__c = '850010100%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&696-0024-04-002%%1%%27%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Moorooka%%&850010100%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&696-0024-04-002%%1%%35%%Network Management%%GeoProbe%%SpIprobe - 2U/14U%%Mascot%%&';
            
        }
        insert quotes;  
        // BigMachines__Quote__c.ensurePrimary - end test
        
        
    
        quotes[0].BigMachines__Is_Primary__c = true;
        update quotes; 
        quotes[0].BigMachines__Is_Primary__c = false;
        quotes[1].BigMachines__Is_Primary__c = true;
        update quotes; 
        
                
        
        updateBOMLater(quotes[1].id, opty.id, quotes[1].BOM__c,true);
        // BigMachinesSyncBOMClass.syncQuoteWithOpty - end positive test
    } 
}

 

I have just been asked by management to explore options managing one master opportunity comprised by group of individual opportunities. Today we are managing this individually and currently have no way to tie them together to represent the one opportunity.

 

I am looking for a way to:

  • Create one master opportunity 
  • Batch create child opportunity records (designated number) 
  • Roll-up the $ amount of child opportunity records to the $ amount of the master opportunity
  • Forecast/Report on the master opportunity to reflect open vs. closed as each individual opportunity is closed

Note: We utilize BigMachines for quoting

 

Use case:

 

There is one big project for Acme Telecom that's worth $1M. This is captured in SF.com as 1 opportunity for $1M. This customer has asked that we break out the project in 10 phases and provide 1 quote for each phase. Since we could only have 1 primary quote per opportunity, we would have to create 10 separate opportunities worth $100K per quote. 

 

However, our sales management would like to report/forecast the 1 opportunity. As each quote is booked, the respective opportunity would be closed in SF.com and reflected in the forecasts and reporting. Ultimately, we would end up with $1M of closed opportunities over the course of the FY. 

 

This is scenario starting to occur more frequently and it is becoming a nightmare to manage.  

 

Any ideas?

 Hello,

 

I'm about to pull my hair out here trying to unit test this trigger in order to move it to production. This passes all of my manual use case testing, but I only get 72% code coverage with the apex class unit testing. Not sure what's happening here. Any assistance would be appreciated.

 

Code is provided below, but the following lines are highlighted in red on the test debug:

 

createdsr.add(new Service_Request__c (Opportunity__c = o.Id, Account__c=o.AccountID, Name = o.Name, Service_Group__c = 'RFx'));

 

 

system.debug(Ex);

 

 

Apex Trigger Code:

 

trigger AutomateCreateDSR on Opportunity (after insert,after update) {
List<Service_Request__c> createdsr = new List <Service_Request__c> {};
List<Id> oppIds = new List<Id>{};

for (opportunity o : trigger.new) {
oppIds.add(o.id);

{
List<Service_Request__c> dsr= [SELECT Id,Opportunity__c,Account__c,Name,Service_Group__c FROM Service_Request__c WHERE Opportunity__c IN :oppIds];
if (dsr.size()==0 && o.Point_by_Point_Response__c ==True)
{
createdsr.add(new Service_Request__c (Opportunity__c = o.Id, Account__c=o.AccountID, Name = o.Name, Service_Group__c = 'RFx'));
}

try {
insert createdsr;
}
catch (Exception Ex)
{
system.debug(Ex);
}
}
}
}
 
 
 
 

 

Apex Class Test Code:

 

@isTest
private class TestAutomateDSR {

   private static Opportunity opportunity1;
    
    static {
        
        opportunity1 = new Opportunity();
        opportunity1.Name = 'TestOpp1';
        opportunity1.StageName = '1-Targeted';
        opportunity1.CloseDate = Date.valueOf('2011-09-01');
        opportunity1.Amount = 200;
        //opportunity1.Has_Orders__c = false;

        insert opportunity1;            
    }
        
    static testMethod void testhasDSRs() {
    List<Service_Request__c> createdsr = new List <Service_Request__c> {};
   
    createdsr.add(new Service_Request__c (Opportunity__c = opportunity1.Id, Account__c=opportunity1.AccountID, Name = opportunity1.Name, Service_Group__c = 'RFx'));  
            
      try {
  insert createdsr;
   }
  catch (Exception Ex)
  {
  system.debug(Ex);
   }
   }
   }
 

 

Hello,

 

I am a newbie to apex coding, but trying to figure out a way to override the opportunity amount once opportunity products have been added. Through research, I was able to write a trigger that allows my sales reps to override the amount on an opportunity with Opportunity products. BTW, we utilize BigMachines for quoting, so the opportunity products are sync'd over from BigMachines each time the quote is updated. 

 

As I mentioned before, this solution works, but in order to remove the override flag and revert back to the quote amount, the salesrep must go back into BigMachines and re-save the quote record to initiate the product update thus updating the amount. What I would like to do is figure out a way to insert logic in the For statement that will either replace the Unit Price with "RealAmount" if the override flag = true  OR utilize Unit Price if override flag is not True.

 

Any ideas? Trigger code is below:

 

 

 

trigger OverrideLISalesPrice2 on Opportunity (after insert,after update) {
List<Id> oppIds = new List<Id>{};

for (Opportunity o : Trigger.new)

{
if (o.Use_Actual_Amount__c == True && o.HasOpportunityLineItem == true)
    oppIds.add(o.id);
}

 List<OpportunityLineItem> theLines = [SELECT Id,UnitPrice,RealAmount__c FROM OpportunityLineItem WHERE OpportunityId IN :oppIds];
 
   
    for(OpportunityLineItem OLI : theLines)  
                    {  
                        OLI.UnitPrice = OLI.RealAmount__c;  
                    }  
                update theLines;