• TheReportDoctor
  • NEWBIE
  • 99 Points
  • Member since 2010

  • Chatter
    Feed
  • 4
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 24
    Questions
  • 23
    Replies

I am able to setup record types in the Dev Environment for Opportunities, but when I create  a new Opportunity it does not ask me for what Record Type I want.  Any suggestions?

 

Hugh

I have a lookup field and in the page layout I have defined it as read-only.  When I edit the object in that page the field is updatable.  Any suggestions?

 

TRD

When I can for my form, which holds my detail object, to be rerended only the related list gets rerendered, but the field that I updated does not refresh with the new value.  If I press F5 to refresh the page it appears.  This field needs to be populated before my related list can populate, so we know that the underlying field is updated it just does not appear.  Here is my code.  Thank you for your time. TRD

 

<apex:page standardController="Opportunity" extensions="workFlowData"  >
        <apex:form id="oppsPage"  rendered="{!renderMe}">
            <apex:actionFunction name="postWorkFlow" action="{!postWorkFlow}" rerender="oppsPage" />
            <apex:pageblock >
                <apex:selectList value="{!flow}" size="1" onchange="postWorkFlow()" >
                    <apex:selectOptions value="{!WFNames}"/>
                </apex:selectList>
                <apex:pagemessages />
            </apex:pageblock>
            <apex:detail id="oppsForm" subject="{!$CurrentPage.parameters.Id}" rendered="true"/>
        </apex:form>
</apex:page>

 

public class workFlowData {
    String selectedWorkFlow;
    
    public Opportunity opp {
        get;
        set;
    }
    
    public workFlowData(ApexPages.StandardController stdController) {
        this.opp = (Opportunity)stdController.getRecord();
        if (this.opp.id != null) {
            this.opp = [SELECT Product__c, Stage_of_Install__c, workflow__c FROM Opportunity WHERE Id = :this.opp.Id];
        }
    }
 
    public List<SelectOption> getWFNames() {
        List<Workflow__c> wf_names = [SELECT id, name FROM Workflow__c ORDER BY name];
        List<SelectOption> wf_dropdown= new List<SelectOption>();
        wf_dropdown.add(new SelectOption('',''));
        for (Workflow__c wf_name: wf_names) {
            wf_dropdown.add(new SelectOption(wf_name.id,wf_name.name));
        }
        return wf_dropdown;
    }
    
    public String flow {
        get;
        set;
    }
    
    public Boolean getRenderMe() {
        return this.opp.Product__c!= null && this.opp.Stage_of_Install__c == '7 - Pipeline';
    }
    
    public PageReference postWorkFlow() {
        if (this.opp.Id != null) {
            this.opp.workflow__c = this.flow;
            try {
                update opp;
            } catch (dmlException de) {
                for (Integer err =0; err < de.getNumDml();err++) {
                    system.debug(de.getDmlMessage(err));
                }
            }
        }
        return null;
    }
}

 

Error Message:

 

System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Opportunity.Product__c

<apex:page standardController="Opportunity" extensions="workFlowData" id="oppsPage">
        <apex:form rendered="{!renderMe}">
        <apex:pageblock >
            <apex:selectList value="{!flows}" size="1">
                <apex:selectOptions value="{!WFNames}"/>
            </apex:selectList>
            <apex:actionSupport event="onchange" rerender="oppsPage" status="status"/>
        </apex:pageblock>
        </apex:form>
        <apex:detail />
</apex:page>

 

public class workFlowData {
    private final Opportunity opp;
    String[] flows = new String[]{};
    
    public workFlowData(ApexPages.StandardController stdController) {
        this.opp = (Opportunity)stdController.getRecord();
    }
    
    public Opportunity getOpp() {
        return opp;
    }
    
    public List<SelectOption> getWFNames() {
        List<Workflow__c> wf_names = [SELECT id, name FROM Workflow__c ORDER BY name];
        List<SelectOption> wf_dropdown= new List<SelectOption>();
        wf_dropdown.add(new SelectOption('',''));
        for (Workflow__c wf_name: wf_names) {
            wf_dropdown.add(new SelectOption(wf_name.id,wf_name.name));
        }
        return wf_dropdown;
    }
    
    public String[] getFlows() {
        return flows;
    }
    
    public void setFlows(String[] flows) {
        this.flows = flows;
    }
    
    public Boolean getRenderMe() {
        return opp.Product__c == null ;
    }
}

 

 

Thanks for your help.

 

TRD

I have a page layout for Opportuntiy.  I have set the field Workflow to read only.  I did this for every version of the page layout.  Workflow is a lookup relationship field.  When I go into to edit or create a new Opportunity the field is updatable.

 

Thanks for your assistance.

 

TRD

VLOOKUP(TEXT( $ObjectType.Workflow__c.Fields.Stage_of_Install__c) , TEXT($ObjectType.Workflow__c.Fields.Name) , Workflow__c ) <> TEXT(Stage_of_Install__c)

 

The above code gives me the error, "Error: Incorrect parameter for function TEXT(). Expected Number, Date, DateTime, Picklist, received Object"

 

The object, "$ObjectType.Workflow__c.Fields.Stage_of_Install__c" IS a Picklist.

 

Thanks for your input!

 

TRD

I got the message, "Failed to send request to https://login.salesforce.com/services/Soap/u/18.0" when trying to login. Server Host is set to https://login.salesforce.com just like version 17.0. I could NOT find the 18.0 version of the documentation online. TRD

I have a list of project steps.  Starting with the first step I calc the start date as today in an insert trigger.  Works great.  The first step gets updated and kicks of an update trigger.

 

The update trigger updates the next step(s) in the project plan with a calculation of the current start date plus it's intervals. These steps trigger the update in the successor steps etc...

 

Nice little loop of triggers.  Until we get over th 21 SOQL limit.  Any suggestions on how to complete this logic without all the troubles of triggers kicking triggers?

 

I have already worked with @future - It errors because an @future method cannot call another @future method and the code doesn't call another one but it causes an update trigger that calls one.

 

I am aware of keeping SOQL and DML outside the loop and that is considered in my design.

 

I am using list instead of call each record one at a time where I can.

 

If you want to see the code it is about 250 lines and I can add it, but I am not looking for the code syntax as much as the approach to the problem.

 

Thanks

 

TRD

Why am I getting the error "Error: Compile Error: Unsupported parameter type SOBJECT:Provisioning__c at line 3 column 24" when I try to save this code in my dev edition?  The code works without the "@future".

 

global class provision { @future public static void updateEstDates (provisioning__c currentRecord ){ String opportunityID = currentRecord.Opportunity__c; String provisioningId = currentRecord.Id; Date maxLastEndDate; List<provisioning__c> steps = [SELECT processStep__c , predecessorStep__c , successorStep__c , Est_Start_Date__c , Est_End_Date__c , Interval__c FROM provisioning__c WHERE Opportunity__c = :opportunityID ORDER BY predecessorStep__c]; for( provisioning__c eachStep: steps) { // track the max last date from those who share my successor maxLastEndDate= null; if (eachStep.predecessorStep__c == 0 && maxLastEndDate == null) { maxLastEndDate = system.today(); } else { for(provisioning__c previousStep: steps) { if (previousStep.processStep__c == eachStep.predecessorStep__c || previousStep.successorStep__c == eachStep.processStep__c) { if (maxLastEndDate < previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue())|| maxLastEndDate == null) { maxLastEndDate= previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue()); } } } } if (eachStep.ID != provisioningId || (eachStep.ID == provisioningId && eachStep.Est_Start_Date__c == null)) { if (maxLastEndDate != null) { eachStep.Est_Start_Date__c = maxLastEndDate; } else { eachStep.Est_Start_Date__c = system.today(); } // User's should not change Est_End_Dates. Update the Intervals only!! if (eachStep.Interval__c == null) { eachStep.Interval__c = 0 ; } } } try { update steps; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { Trigger.new[0].AddError(de.getDmlMessage(i)); } } } }

 

I am running out of ideas.

 

I have two objects using update triggers.

 

The first one updates items on the second one.  The second one fires off it's update trigger causing too many DML's.

 

When the first object fires off the update trigger I want to stop the second table from doing some of the functions in it's update trigger.

 

Does anyone have the million dollar answer?

 

Here is the code:

 

trigger OpportunityAfterUpdateInsert on Opportunity (after update, after insert) { String status; Integer record = 0; Integer countSteps = 0; for (Opportunity opp: Trigger.new) { String opportunityId = opp.Id; String productId = opp.Product__c; if ((opp.Stage_Of_Install__c =='7 - Pipeline' || opp.Stage_Of_Install__c =='10 - Disconnected' ) && opp.AccountId != null) { List<Provisioning__c> completedTask = [SELECT ID FROM Provisioning__c WHERE Opportunity__c = :opportunityId AND status__c = '3 - Completed']; if (!completedTask.isEmpty()) { opp.AddError('>>>You can not change the product if there are any completed tasks.'); } if (Trigger.isUpdate) { if (Trigger.new[record].Product__c != Trigger.old[record].Product__c) { opp.AddError('You cannot change products on an opportunity in 7 - Pipeline'); } String oldProductId = Trigger.old[record].Product__c; countSteps = [SELECT count() FROM Provisioning__c WHERE Opportunity__c = :opportunityId AND Product__c = :oldProductId ]; } if (countSteps == 0) { List<Provisioning__c> provisioning = [SELECT Account__c FROM Provisioning__c WHERE Opportunity__c = :opportunityId]; try { delete provisioning ; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } if (opp.Stage_Of_Install__c =='7 - Pipeline') { List<ProductProcesses__c> provisioningSteps= [SELECT Department__c , Interval__c , PredecessorStep__c , ProcessStep__c , SuccessorStep__c , WorkSteps__c FROM ProductProcesses__c WHERE Product__c = :productId ORDER BY ProcessStep__c]; if (!provisioningSteps.isEmpty()) { for (ProductProcesses__c productStep: provisioningSteps) { if (productStep.PredecessorStep__c == 0 ) { status = '1 - Active Step'; } else { status = '2 - Pending'; } provisioning.add(new Provisioning__c ( Account__c = opp.AccountId , Department__c = productStep.Department__c , Interval__c = productStep.Interval__c , Opportunity__c = opp.Id , PredecessorStep__c = productStep.PredecessorStep__c , ProcessStep__c = productStep.ProcessStep__c , Product__c = opp.Product__c , Status__c = status , SuccessorStep__c = productStep.SuccessorStep__c , WorkSteps__c = productStep.WorkSteps__c)); } try { insert provisioning; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } } } else { List<ProductDisconnect__c> disconnectSteps = [SELECT Department__c , Interval__c , PredecessorStep__c , ProcessStep__c , SuccessorStep__c , WorkSteps__c FROM ProductDisconnect__c WHERE Product__c = :productId ORDER BY ProcessStep__c]; if (!disconnectSteps.isEmpty()) { for (ProductDisconnect__c productStep: disconnectSteps ) { if (productStep.PredecessorStep__c == 0 ) { status = '1 - Active Step'; } else { status = '2 - Pending'; } provisioning.add(new Provisioning__c ( Account__c = opp.AccountId , Department__c = productStep.Department__c , Interval__c = productStep.Interval__c , Opportunity__c = opp.Id , PredecessorStep__c = productStep.PredecessorStep__c , ProcessStep__c = productStep.ProcessStep__c , Product__c = opp.Product__c , Status__c = status , SuccessorStep__c = productStep.SuccessorStep__c , WorkSteps__c = productStep.WorkSteps__c)); } try { insert provisioning; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } } } } provision.updateEstDates([SELECT Id , Opportunity__c FROM provisioning__c WHERE Opportunity__c = : opportunityId AND predecessorStep__c = 0 LIMIT 1]); } record ++; } }

 

 

trigger ProvisioningAfterUpdate on Provisioning__c (after update) { for(Integer l = 0; l < Trigger.new.size(); l++) { String currentId = Trigger.new[l].Id; String opportunityID = Trigger.new[l].Opportunity__c; Double currentPredecessorStep = Trigger.new[l].PredecessorStep__c; Double currentProcessStep = Trigger.new[l].ProcessStep__c; Double currentSuccessorStep = Trigger.new[l].SuccessorStep__c; if (Trigger.new[l].status__c == '1 - Active Step') { if (Trigger.old[l].status__c == '3 - Completed' && Trigger.new[l].SuccessorStep__c != 99 ) { // Uncomplete Integer parallelSteps = [SELECT count() FROM Provisioning__c WHERE Opportunity__c = :opportunityID AND processStep__c != :currentProcessStep AND successorStep__c =: currentSuccessorStep AND status__c IN ('1 - Active Step')]; Integer completedSteps = [SELECT count() FROM Provisioning__c WHERE Opportunity__c = :opportunityID AND (processStep__c = :currentSuccessorStep OR predecessorStep__c = :currentProcessStep) AND status__c = '3 - Completed']; if (completedSteps != 0 ) { //Return Completed date Provisioning__c editDate = [SELECT Completed_Date__c FROM Provisioning__c WHERE Id = :currentId]; editDate.Completed_Date__c = Trigger.old[l].Completed_Date__c; try { update editDate; } catch (dmlException de) { for(Integer err = 0; err < de.getNumDml(); err++) { Trigger.new[l].AddError(de.getDmlMessage(err)); } } Trigger.new[l].AddError('Cannot revert the completed step when successor is completed.'); } else { if (parallelSteps == 0 && completedSteps == 0) { List<Provisioning__c> Steps = [SELECT status__c FROM Provisioning__c WHERE Opportunity__c = :opportunityID AND (processStep__c = :currentSuccessorStep OR predecessorStep__c = :currentProcessStep) AND status__c = '1 - Active Step']; if (Steps.isEmpty()) { // Return Completed date Provisioning__c editDate = [SELECT Completed_Date__c FROM Provisioning__c WHERE Id = :currentId]; editDate.Completed_Date__c = Trigger.old[l].Completed_Date__c; try { update editDate; } catch (dmlException de) { for(Integer err = 0; err < de.getNumDml(); err++) { Trigger.new[l].AddError(de.getDmlMessage(err)); } } Trigger.new[l].AddError('Broken uncompleting links in the provisioning plan.'); } else { for(Provisioning__c Step: Steps) { Step.status__c = '2 - Pending'; } try { update Steps; } catch (dmlException de){ for (Integer err = 0; err < de.getNumDml(); err++) { Trigger.new[l].AddError(de.getDmlMessage(err)); } } } } } } } else if (Trigger.new[l].status__c == '3 - Completed') { if (Trigger.old[l].status__c != '1 - Active Step') { Trigger.new[l].AddError('Only 1 - Active Steps can be changed to 3 - Completed. (After Update)'); } else if (Trigger.new[l].SuccessorStep__c != 99) { // Review and update next active steps Integer parallelSteps = [SELECT count() FROM Provisioning__c WHERE Opportunity__c = :opportunityID AND successorStep__c =: currentSuccessorStep AND status__c != '3 - Completed']; if (parallelSteps == 0 ) { List<Provisioning__c> Steps = [SELECT status__c FROM Provisioning__c WHERE Opportunity__c = :opportunityID AND (processStep__c = :currentSuccessorStep OR predecessorStep__c = :currentProcessStep)]; if (Steps.isEmpty()) { Trigger.new[l].AddError('Broken completing links in the provisioning plan. '); } else { for (Provisioning__c Step: Steps) { Step.status__c = '1 - Active Step'; } try { update Steps; } catch (dmlException de){ for (Integer err = 0; err < de.getNumDml(); err++) { Trigger.new[l].AddError(de.getDmlMessage(err)); } } } } } } else if (Trigger.new[l].status__c == '4 - Delete Step') { if (Trigger.old[l].status__c != '2 - Pending') { Trigger.new[l].AddError('Only 2 - Pending steps can be changed to 4 - Delete Step.'); } else { // Just delete the step and the delete trigger will take care of the rest List<Provisioning__c> deleteRecord = [SELECT ID FROM Provisioning__c WHERE Id =:currentId ]; try { delete deleteRecord; } catch (dmlException de) { for (Integer err = 0; err < de.getNumDml(); err++) { Trigger.new[l].AddError(de.getDmlMessage(err)); } } } } else if (Trigger.new[l].status__c == '2 - Pending') { } else { Trigger.new[l].AddError('Invalid Status selected (After Update).'); } if (Trigger.new[l].status__c != '4 - Delete Step' && Trigger.old[l].Est_Start_Date__c != Trigger.new[l].Est_Start_Date__c ) { provision.updateEstDates([SELECT Id , Opportunity__c FROM provisioning__c WHERE Id =:currentId]); } } }

 

 

 

public class provision { public static void updateEstDates (provisioning__c currentRecord ){ String opportunityID = currentRecord.Opportunity__c; String provisioningId = currentRecord.Id; Date maxLastEndDate; List<provisioning__c> steps = [SELECT processStep__c , predecessorStep__c , successorStep__c , Est_Start_Date__c , Est_End_Date__c , Interval__c FROM provisioning__c WHERE Opportunity__c = :opportunityID ORDER BY predecessorStep__c]; for( provisioning__c eachStep: steps) { // track the max last date from those who share my successor maxLastEndDate= null; if (eachStep.predecessorStep__c == 0 && maxLastEndDate == null) { maxLastEndDate = system.today(); } else { for(provisioning__c previousStep: steps) { if (previousStep.processStep__c == eachStep.predecessorStep__c || previousStep.successorStep__c == eachStep.processStep__c) { if (maxLastEndDate < previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue())|| maxLastEndDate == null) { maxLastEndDate= previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue()); } } } } if (eachStep.ID != provisioningId || (eachStep.ID == provisioningId && eachStep.Est_Start_Date__c == null)) { if (maxLastEndDate != null) { eachStep.Est_Start_Date__c = maxLastEndDate; } else { eachStep.Est_Start_Date__c = system.today(); } // User's should not change Est_End_Dates. Update the Intervals only!! if (eachStep.Interval__c == null) { eachStep.Interval__c = 0 ; } } } try { update steps; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { Trigger.new[0].AddError(de.getDmlMessage(i)); } } } }

 

I have a calculated field.  When I set values in the record via a class and then I look to the formula field it is null.  Is there a way I can say do the calc now?

 

TRD

I am calling my new method from a trigger and I get the above error.

 

The line calling the method is near the bottom.

 

trigger OpportunityAfterUpdateInsert on Opportunity (after update, after insert) { String status; Integer record = 0; Integer countSteps = 0; for (Opportunity opp: Trigger.new) { String opportunityId = opp.Id; String productId = opp.Product__c; if ((opp.Stage_Of_Install__c =='7 - Pipeline' || opp.Stage_Of_Install__c =='10 - Disconnected' ) && opp.AccountId != null) { List<Provisioning__c> completedTask = [SELECT ID FROM Provisioning__c WHERE Opportunity__c = :opportunityId AND status__c = '3 - Completed']; if (!completedTask.isEmpty()) { opp.AddError('>>>You can not change the product if there are any completed tasks.'); } if (Trigger.isUpdate) { if (Trigger.new[record].Product__c != Trigger.old[record].Product__c) { opp.AddError('You cannot change products on an opportunity in 7 - Pipeline'); } String oldProductId = Trigger.old[record].Product__c; countSteps = [SELECT count() FROM Provisioning__c WHERE Opportunity__c = :opportunityId AND Product__c = :oldProductId ]; } if (countSteps == 0) { List<Provisioning__c> provisioning = [SELECT Account__c FROM Provisioning__c WHERE Opportunity__c = :opportunityId]; try { delete provisioning ; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } if (opp.Stage_Of_Install__c =='7 - Pipeline') { List<ProductProcesses__c> provisioningSteps= [SELECT Department__c , Interval__c , PredecessorStep__c , ProcessStep__c , SuccessorStep__c , WorkSteps__c FROM ProductProcesses__c WHERE Product__c = :productId ORDER BY ProcessStep__c]; if (!provisioningSteps.isEmpty()) { for (ProductProcesses__c productStep: provisioningSteps) { if (productStep.PredecessorStep__c == 0 ) { status = '1 - Active Step'; } else { status = '2 - Pending'; } provisioning.add(new Provisioning__c ( Account__c = opp.AccountId , Department__c = productStep.Department__c , Interval__c = productStep.Interval__c , Opportunity__c = opp.Id , PredecessorStep__c = productStep.PredecessorStep__c , ProcessStep__c = productStep.ProcessStep__c , Product__c = opp.Product__c , Status__c = status , SuccessorStep__c = productStep.SuccessorStep__c , WorkSteps__c = productStep.WorkSteps__c)); } try { insert provisioning; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } } } else { List<ProductDisconnect__c> disconnectSteps = [SELECT Department__c , Interval__c , PredecessorStep__c , ProcessStep__c , SuccessorStep__c , WorkSteps__c FROM ProductDisconnect__c WHERE Product__c = :productId ORDER BY ProcessStep__c]; if (!disconnectSteps.isEmpty()) { for (ProductDisconnect__c productStep: disconnectSteps ) { if (productStep.PredecessorStep__c == 0 ) { status = '1 - Active Step'; } else { status = '2 - Pending'; } provisioning.add(new Provisioning__c ( Account__c = opp.AccountId , Department__c = productStep.Department__c , Interval__c = productStep.Interval__c , Opportunity__c = opp.Id , PredecessorStep__c = productStep.PredecessorStep__c , ProcessStep__c = productStep.ProcessStep__c , Product__c = opp.Product__c , Status__c = status , SuccessorStep__c = productStep.SuccessorStep__c , WorkSteps__c = productStep.WorkSteps__c)); } try { insert provisioning; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } } } provisioning__c firstRec = [SELECT processStep__c , successorStep__c , predecessorStep__c , Est_Start_Date__c , Est_End_Date__c , Id , Opportunity__c FROM provisioning__c WHERE Opportunity__c = :opportunityId AND successorStep__c = 0 ORDER BY processStep__c LIMIT 1 ]; provisioning.updateEstDates(firstRec); } } record ++; } }

 

 

Here is the class and method that I am trying to call:

 

public class provisioning { public static void testme () { //no comment } public static void updateEstDates (provisioning__c currentRecord ){ String opportunityID = currentRecord.Opportunity__c; Double currentSuccessor = currentRecord.processStep__c; String provisioningId = currentRecord.Id; Date maxLastEndDate; List<provisioning__c> steps = [SELECT processStep__c , predecessorStep__c , successorStep__c , Est_Start_Date__c , Est_End_Date__c , Interval__c FROM provisioning__c WHERE successorStep__c >= :currentSuccessor AND Opportunity__c = :opportunityID AND Id != :provisioningId ORDER BY successorStep__c]; for( provisioning__c eachStep: steps) { if (eachStep.successorStep__c != 99 ) { // track the max last date from those who share my successor for(provisioning__c previousStep: steps) { maxLastEndDate= null; if (previousStep.successorStep__c == 0) { maxLastEndDate = system.today(); } else { if (previousStep.successorStep__c == eachStep.processStep__c) { if (maxLastEndDate< previousStep.Est_End_Date__c) { maxLastEndDate= previousStep.Est_End_Date__c; } } } } eachStep.Est_Start_Date__c = maxLastEndDate; // User's should not change Est_End_Dates. Update the Intervals only!! eachStep.Est_End_Date__c = eachStep.Est_Start_Date__c.addDays(Integer.valueOf(eachStep.Interval__c)); } } } }

 

 

Your time and assistance is greatly appreciated.

 

TRD

 

I want to add a new mother object record and add a new child record.  I cannot insert the mother record until the end of the batch.  There will be multiple mother records.  How can I give the child record the mother's ID before the mother is saved?  Can I add the mother and child in the same DML add function?  It doesn't work for me currently.

 

 

In the following sample of code.  I want to find values from the fields in the Opportunity object.  This trigger is from the OpportunityLineItem.  The Apex Explorer says I should be able to address those fields as li.Opportunity.FieldName.  When I do that no matter what field I am looking at the come across NULL.  The tempation is to use "Opportunity__r", but that does not work. Any suggestions? 

 

 

trigger OpportunityFulfillmentItem on OpportunityLineItem (after insert, after update) {
    String opID;
    String liID;
    String pbID;
    String wsID;
    String newStatus;
    for(OpportunityLineItem li : trigger.new) {
   li.AddError('Hi Hugh: ' + trigger.new[0].Opportunity.CloseDate);
           if (li.Opportunity.Stage_of_Install__c == '7 - Pipeline') {
               opID = li.OpportunityId;
               liID = li.PricebookEntryId;

I have received the following error when I use the new Apex Data Loader Version 18.0.  My code worked fine with version 17.0.  The best documentation I can find on the error is that their is a method that I am calling (SOAP) that is not available.  Did version 18.0 drop something that was 17.0?

 

2002 [accountToHoldingCompany] ERROR com.salesforce.dataloader.process.ProcessRunner  - Invalid Api version specified on URL Exception in thread "main" java.lang.RuntimeException: [UnexpectedErrorFault [ApiFault  exceptionCode='UNSUPPORTED_API_VERSION' exceptionMessage='Invalid Api version specified on URL'

First, I want to appoligize.  I don't think this issue belongs here but I could not find the proper community for it.  Searching salesforce.com and the web turns up nothing.

 

Under users Profiles there is an options to check or uncheck Password Never Expires.  When I go under the System Administrator's profile to edit the profile that checkbox is disabled.

 

Does anyone know how to enable it?

 

I do not want to use the Password Policy and set everyone's password to not expire.  I only want to set it for the System Administrator.

 

This issues exists in both the Enterprise and Developer additions.

 

Please don't reply with random suggestions.  I wish only to hear from those who have seen this problem and have successfuly resolved it.

 

Salesforce.com allows the user to enter the name of a custom object record multiple times.  Is there a validation rule or a setting that I don't see to make this unique?
Is there a way to track what fired a trigger.  Example:  Was the trigger caused by the user updating the data, was the trigger caused by another trigger updating the data, or was the trigger caused by a batch process?
I have two workspaces in Eclipse.  One for production (linked to a production version of  salesforce.com) and one for development (linked to a development edition of salesforce.com).  The production one returns details of the execution including the system.debug ouput.  The log level in production is set to Debug.  If I run the same code in the development environment it only returns 'Anonymous execution was successful' no matter what setting you use for the log level.
I have three custom objects:  productProcesses, fulfillment, and fulfillmentDependencies.  I want to create a Master-Detail field in fulfillmentDependencies(Detail) that links to fulfillment (Master).  When I create the Master-Detail field the drop-down list of available objects shows productProcesses but not fulfillment.  How can I get fulfillment on the drop-down list of available Master-Detail relationships?

Hi :

   If I have:

 

List<Decimal> rTypes2 = new List<Decimal>(); for(Account rType :[SELECT Term FROM Subject]) { rTypes2.add(rType.Term); } for(Account a:trigger.new){ if(rTypes2.get('Term') = 9.1) {} } I am getting an error on rTypes2.get('Term')?????

 

I am getting an error on rTypes2.get('Term')?????
 

 

I have a list of project steps.  Starting with the first step I calc the start date as today in an insert trigger.  Works great.  The first step gets updated and kicks of an update trigger.

 

The update trigger updates the next step(s) in the project plan with a calculation of the current start date plus it's intervals. These steps trigger the update in the successor steps etc...

 

Nice little loop of triggers.  Until we get over th 21 SOQL limit.  Any suggestions on how to complete this logic without all the troubles of triggers kicking triggers?

 

I have already worked with @future - It errors because an @future method cannot call another @future method and the code doesn't call another one but it causes an update trigger that calls one.

 

I am aware of keeping SOQL and DML outside the loop and that is considered in my design.

 

I am using list instead of call each record one at a time where I can.

 

If you want to see the code it is about 250 lines and I can add it, but I am not looking for the code syntax as much as the approach to the problem.

 

Thanks

 

TRD

Why am I getting the error "Error: Compile Error: Unsupported parameter type SOBJECT:Provisioning__c at line 3 column 24" when I try to save this code in my dev edition?  The code works without the "@future".

 

global class provision { @future public static void updateEstDates (provisioning__c currentRecord ){ String opportunityID = currentRecord.Opportunity__c; String provisioningId = currentRecord.Id; Date maxLastEndDate; List<provisioning__c> steps = [SELECT processStep__c , predecessorStep__c , successorStep__c , Est_Start_Date__c , Est_End_Date__c , Interval__c FROM provisioning__c WHERE Opportunity__c = :opportunityID ORDER BY predecessorStep__c]; for( provisioning__c eachStep: steps) { // track the max last date from those who share my successor maxLastEndDate= null; if (eachStep.predecessorStep__c == 0 && maxLastEndDate == null) { maxLastEndDate = system.today(); } else { for(provisioning__c previousStep: steps) { if (previousStep.processStep__c == eachStep.predecessorStep__c || previousStep.successorStep__c == eachStep.processStep__c) { if (maxLastEndDate < previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue())|| maxLastEndDate == null) { maxLastEndDate= previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue()); } } } } if (eachStep.ID != provisioningId || (eachStep.ID == provisioningId && eachStep.Est_Start_Date__c == null)) { if (maxLastEndDate != null) { eachStep.Est_Start_Date__c = maxLastEndDate; } else { eachStep.Est_Start_Date__c = system.today(); } // User's should not change Est_End_Dates. Update the Intervals only!! if (eachStep.Interval__c == null) { eachStep.Interval__c = 0 ; } } } try { update steps; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { Trigger.new[0].AddError(de.getDmlMessage(i)); } } } }

 

I am running out of ideas.

 

I have two objects using update triggers.

 

The first one updates items on the second one.  The second one fires off it's update trigger causing too many DML's.

 

When the first object fires off the update trigger I want to stop the second table from doing some of the functions in it's update trigger.

 

Does anyone have the million dollar answer?

 

Here is the code:

 

trigger OpportunityAfterUpdateInsert on Opportunity (after update, after insert) { String status; Integer record = 0; Integer countSteps = 0; for (Opportunity opp: Trigger.new) { String opportunityId = opp.Id; String productId = opp.Product__c; if ((opp.Stage_Of_Install__c =='7 - Pipeline' || opp.Stage_Of_Install__c =='10 - Disconnected' ) && opp.AccountId != null) { List<Provisioning__c> completedTask = [SELECT ID FROM Provisioning__c WHERE Opportunity__c = :opportunityId AND status__c = '3 - Completed']; if (!completedTask.isEmpty()) { opp.AddError('>>>You can not change the product if there are any completed tasks.'); } if (Trigger.isUpdate) { if (Trigger.new[record].Product__c != Trigger.old[record].Product__c) { opp.AddError('You cannot change products on an opportunity in 7 - Pipeline'); } String oldProductId = Trigger.old[record].Product__c; countSteps = [SELECT count() FROM Provisioning__c WHERE Opportunity__c = :opportunityId AND Product__c = :oldProductId ]; } if (countSteps == 0) { List<Provisioning__c> provisioning = [SELECT Account__c FROM Provisioning__c WHERE Opportunity__c = :opportunityId]; try { delete provisioning ; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } if (opp.Stage_Of_Install__c =='7 - Pipeline') { List<ProductProcesses__c> provisioningSteps= [SELECT Department__c , Interval__c , PredecessorStep__c , ProcessStep__c , SuccessorStep__c , WorkSteps__c FROM ProductProcesses__c WHERE Product__c = :productId ORDER BY ProcessStep__c]; if (!provisioningSteps.isEmpty()) { for (ProductProcesses__c productStep: provisioningSteps) { if (productStep.PredecessorStep__c == 0 ) { status = '1 - Active Step'; } else { status = '2 - Pending'; } provisioning.add(new Provisioning__c ( Account__c = opp.AccountId , Department__c = productStep.Department__c , Interval__c = productStep.Interval__c , Opportunity__c = opp.Id , PredecessorStep__c = productStep.PredecessorStep__c , ProcessStep__c = productStep.ProcessStep__c , Product__c = opp.Product__c , Status__c = status , SuccessorStep__c = productStep.SuccessorStep__c , WorkSteps__c = productStep.WorkSteps__c)); } try { insert provisioning; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } } } else { List<ProductDisconnect__c> disconnectSteps = [SELECT Department__c , Interval__c , PredecessorStep__c , ProcessStep__c , SuccessorStep__c , WorkSteps__c FROM ProductDisconnect__c WHERE Product__c = :productId ORDER BY ProcessStep__c]; if (!disconnectSteps.isEmpty()) { for (ProductDisconnect__c productStep: disconnectSteps ) { if (productStep.PredecessorStep__c == 0 ) { status = '1 - Active Step'; } else { status = '2 - Pending'; } provisioning.add(new Provisioning__c ( Account__c = opp.AccountId , Department__c = productStep.Department__c , Interval__c = productStep.Interval__c , Opportunity__c = opp.Id , PredecessorStep__c = productStep.PredecessorStep__c , ProcessStep__c = productStep.ProcessStep__c , Product__c = opp.Product__c , Status__c = status , SuccessorStep__c = productStep.SuccessorStep__c , WorkSteps__c = productStep.WorkSteps__c)); } try { insert provisioning; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } } } } provision.updateEstDates([SELECT Id , Opportunity__c FROM provisioning__c WHERE Opportunity__c = : opportunityId AND predecessorStep__c = 0 LIMIT 1]); } record ++; } }

 

 

trigger ProvisioningAfterUpdate on Provisioning__c (after update) { for(Integer l = 0; l < Trigger.new.size(); l++) { String currentId = Trigger.new[l].Id; String opportunityID = Trigger.new[l].Opportunity__c; Double currentPredecessorStep = Trigger.new[l].PredecessorStep__c; Double currentProcessStep = Trigger.new[l].ProcessStep__c; Double currentSuccessorStep = Trigger.new[l].SuccessorStep__c; if (Trigger.new[l].status__c == '1 - Active Step') { if (Trigger.old[l].status__c == '3 - Completed' && Trigger.new[l].SuccessorStep__c != 99 ) { // Uncomplete Integer parallelSteps = [SELECT count() FROM Provisioning__c WHERE Opportunity__c = :opportunityID AND processStep__c != :currentProcessStep AND successorStep__c =: currentSuccessorStep AND status__c IN ('1 - Active Step')]; Integer completedSteps = [SELECT count() FROM Provisioning__c WHERE Opportunity__c = :opportunityID AND (processStep__c = :currentSuccessorStep OR predecessorStep__c = :currentProcessStep) AND status__c = '3 - Completed']; if (completedSteps != 0 ) { //Return Completed date Provisioning__c editDate = [SELECT Completed_Date__c FROM Provisioning__c WHERE Id = :currentId]; editDate.Completed_Date__c = Trigger.old[l].Completed_Date__c; try { update editDate; } catch (dmlException de) { for(Integer err = 0; err < de.getNumDml(); err++) { Trigger.new[l].AddError(de.getDmlMessage(err)); } } Trigger.new[l].AddError('Cannot revert the completed step when successor is completed.'); } else { if (parallelSteps == 0 && completedSteps == 0) { List<Provisioning__c> Steps = [SELECT status__c FROM Provisioning__c WHERE Opportunity__c = :opportunityID AND (processStep__c = :currentSuccessorStep OR predecessorStep__c = :currentProcessStep) AND status__c = '1 - Active Step']; if (Steps.isEmpty()) { // Return Completed date Provisioning__c editDate = [SELECT Completed_Date__c FROM Provisioning__c WHERE Id = :currentId]; editDate.Completed_Date__c = Trigger.old[l].Completed_Date__c; try { update editDate; } catch (dmlException de) { for(Integer err = 0; err < de.getNumDml(); err++) { Trigger.new[l].AddError(de.getDmlMessage(err)); } } Trigger.new[l].AddError('Broken uncompleting links in the provisioning plan.'); } else { for(Provisioning__c Step: Steps) { Step.status__c = '2 - Pending'; } try { update Steps; } catch (dmlException de){ for (Integer err = 0; err < de.getNumDml(); err++) { Trigger.new[l].AddError(de.getDmlMessage(err)); } } } } } } } else if (Trigger.new[l].status__c == '3 - Completed') { if (Trigger.old[l].status__c != '1 - Active Step') { Trigger.new[l].AddError('Only 1 - Active Steps can be changed to 3 - Completed. (After Update)'); } else if (Trigger.new[l].SuccessorStep__c != 99) { // Review and update next active steps Integer parallelSteps = [SELECT count() FROM Provisioning__c WHERE Opportunity__c = :opportunityID AND successorStep__c =: currentSuccessorStep AND status__c != '3 - Completed']; if (parallelSteps == 0 ) { List<Provisioning__c> Steps = [SELECT status__c FROM Provisioning__c WHERE Opportunity__c = :opportunityID AND (processStep__c = :currentSuccessorStep OR predecessorStep__c = :currentProcessStep)]; if (Steps.isEmpty()) { Trigger.new[l].AddError('Broken completing links in the provisioning plan. '); } else { for (Provisioning__c Step: Steps) { Step.status__c = '1 - Active Step'; } try { update Steps; } catch (dmlException de){ for (Integer err = 0; err < de.getNumDml(); err++) { Trigger.new[l].AddError(de.getDmlMessage(err)); } } } } } } else if (Trigger.new[l].status__c == '4 - Delete Step') { if (Trigger.old[l].status__c != '2 - Pending') { Trigger.new[l].AddError('Only 2 - Pending steps can be changed to 4 - Delete Step.'); } else { // Just delete the step and the delete trigger will take care of the rest List<Provisioning__c> deleteRecord = [SELECT ID FROM Provisioning__c WHERE Id =:currentId ]; try { delete deleteRecord; } catch (dmlException de) { for (Integer err = 0; err < de.getNumDml(); err++) { Trigger.new[l].AddError(de.getDmlMessage(err)); } } } } else if (Trigger.new[l].status__c == '2 - Pending') { } else { Trigger.new[l].AddError('Invalid Status selected (After Update).'); } if (Trigger.new[l].status__c != '4 - Delete Step' && Trigger.old[l].Est_Start_Date__c != Trigger.new[l].Est_Start_Date__c ) { provision.updateEstDates([SELECT Id , Opportunity__c FROM provisioning__c WHERE Id =:currentId]); } } }

 

 

 

public class provision { public static void updateEstDates (provisioning__c currentRecord ){ String opportunityID = currentRecord.Opportunity__c; String provisioningId = currentRecord.Id; Date maxLastEndDate; List<provisioning__c> steps = [SELECT processStep__c , predecessorStep__c , successorStep__c , Est_Start_Date__c , Est_End_Date__c , Interval__c FROM provisioning__c WHERE Opportunity__c = :opportunityID ORDER BY predecessorStep__c]; for( provisioning__c eachStep: steps) { // track the max last date from those who share my successor maxLastEndDate= null; if (eachStep.predecessorStep__c == 0 && maxLastEndDate == null) { maxLastEndDate = system.today(); } else { for(provisioning__c previousStep: steps) { if (previousStep.processStep__c == eachStep.predecessorStep__c || previousStep.successorStep__c == eachStep.processStep__c) { if (maxLastEndDate < previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue())|| maxLastEndDate == null) { maxLastEndDate= previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue()); } } } } if (eachStep.ID != provisioningId || (eachStep.ID == provisioningId && eachStep.Est_Start_Date__c == null)) { if (maxLastEndDate != null) { eachStep.Est_Start_Date__c = maxLastEndDate; } else { eachStep.Est_Start_Date__c = system.today(); } // User's should not change Est_End_Dates. Update the Intervals only!! if (eachStep.Interval__c == null) { eachStep.Interval__c = 0 ; } } } try { update steps; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { Trigger.new[0].AddError(de.getDmlMessage(i)); } } } }

 

I have a calculated field.  When I set values in the record via a class and then I look to the formula field it is null.  Is there a way I can say do the calc now?

 

TRD

I am calling my new method from a trigger and I get the above error.

 

The line calling the method is near the bottom.

 

trigger OpportunityAfterUpdateInsert on Opportunity (after update, after insert) { String status; Integer record = 0; Integer countSteps = 0; for (Opportunity opp: Trigger.new) { String opportunityId = opp.Id; String productId = opp.Product__c; if ((opp.Stage_Of_Install__c =='7 - Pipeline' || opp.Stage_Of_Install__c =='10 - Disconnected' ) && opp.AccountId != null) { List<Provisioning__c> completedTask = [SELECT ID FROM Provisioning__c WHERE Opportunity__c = :opportunityId AND status__c = '3 - Completed']; if (!completedTask.isEmpty()) { opp.AddError('>>>You can not change the product if there are any completed tasks.'); } if (Trigger.isUpdate) { if (Trigger.new[record].Product__c != Trigger.old[record].Product__c) { opp.AddError('You cannot change products on an opportunity in 7 - Pipeline'); } String oldProductId = Trigger.old[record].Product__c; countSteps = [SELECT count() FROM Provisioning__c WHERE Opportunity__c = :opportunityId AND Product__c = :oldProductId ]; } if (countSteps == 0) { List<Provisioning__c> provisioning = [SELECT Account__c FROM Provisioning__c WHERE Opportunity__c = :opportunityId]; try { delete provisioning ; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } if (opp.Stage_Of_Install__c =='7 - Pipeline') { List<ProductProcesses__c> provisioningSteps= [SELECT Department__c , Interval__c , PredecessorStep__c , ProcessStep__c , SuccessorStep__c , WorkSteps__c FROM ProductProcesses__c WHERE Product__c = :productId ORDER BY ProcessStep__c]; if (!provisioningSteps.isEmpty()) { for (ProductProcesses__c productStep: provisioningSteps) { if (productStep.PredecessorStep__c == 0 ) { status = '1 - Active Step'; } else { status = '2 - Pending'; } provisioning.add(new Provisioning__c ( Account__c = opp.AccountId , Department__c = productStep.Department__c , Interval__c = productStep.Interval__c , Opportunity__c = opp.Id , PredecessorStep__c = productStep.PredecessorStep__c , ProcessStep__c = productStep.ProcessStep__c , Product__c = opp.Product__c , Status__c = status , SuccessorStep__c = productStep.SuccessorStep__c , WorkSteps__c = productStep.WorkSteps__c)); } try { insert provisioning; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } } } else { List<ProductDisconnect__c> disconnectSteps = [SELECT Department__c , Interval__c , PredecessorStep__c , ProcessStep__c , SuccessorStep__c , WorkSteps__c FROM ProductDisconnect__c WHERE Product__c = :productId ORDER BY ProcessStep__c]; if (!disconnectSteps.isEmpty()) { for (ProductDisconnect__c productStep: disconnectSteps ) { if (productStep.PredecessorStep__c == 0 ) { status = '1 - Active Step'; } else { status = '2 - Pending'; } provisioning.add(new Provisioning__c ( Account__c = opp.AccountId , Department__c = productStep.Department__c , Interval__c = productStep.Interval__c , Opportunity__c = opp.Id , PredecessorStep__c = productStep.PredecessorStep__c , ProcessStep__c = productStep.ProcessStep__c , Product__c = opp.Product__c , Status__c = status , SuccessorStep__c = productStep.SuccessorStep__c , WorkSteps__c = productStep.WorkSteps__c)); } try { insert provisioning; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { opp.AddError(de.getDmlMessage(i)); } } } } provisioning__c firstRec = [SELECT processStep__c , successorStep__c , predecessorStep__c , Est_Start_Date__c , Est_End_Date__c , Id , Opportunity__c FROM provisioning__c WHERE Opportunity__c = :opportunityId AND successorStep__c = 0 ORDER BY processStep__c LIMIT 1 ]; provisioning.updateEstDates(firstRec); } } record ++; } }

 

 

Here is the class and method that I am trying to call:

 

public class provisioning { public static void testme () { //no comment } public static void updateEstDates (provisioning__c currentRecord ){ String opportunityID = currentRecord.Opportunity__c; Double currentSuccessor = currentRecord.processStep__c; String provisioningId = currentRecord.Id; Date maxLastEndDate; List<provisioning__c> steps = [SELECT processStep__c , predecessorStep__c , successorStep__c , Est_Start_Date__c , Est_End_Date__c , Interval__c FROM provisioning__c WHERE successorStep__c >= :currentSuccessor AND Opportunity__c = :opportunityID AND Id != :provisioningId ORDER BY successorStep__c]; for( provisioning__c eachStep: steps) { if (eachStep.successorStep__c != 99 ) { // track the max last date from those who share my successor for(provisioning__c previousStep: steps) { maxLastEndDate= null; if (previousStep.successorStep__c == 0) { maxLastEndDate = system.today(); } else { if (previousStep.successorStep__c == eachStep.processStep__c) { if (maxLastEndDate< previousStep.Est_End_Date__c) { maxLastEndDate= previousStep.Est_End_Date__c; } } } } eachStep.Est_Start_Date__c = maxLastEndDate; // User's should not change Est_End_Dates. Update the Intervals only!! eachStep.Est_End_Date__c = eachStep.Est_Start_Date__c.addDays(Integer.valueOf(eachStep.Interval__c)); } } } }

 

 

Your time and assistance is greatly appreciated.

 

TRD

 

I want to add a new mother object record and add a new child record.  I cannot insert the mother record until the end of the batch.  There will be multiple mother records.  How can I give the child record the mother's ID before the mother is saved?  Can I add the mother and child in the same DML add function?  It doesn't work for me currently.

 

 

I have a field named Total Students... and trying to do a count() on the object but can not get it to work...

It keeps bringing up this error:

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger TTLs caused an unexpected exception, contact your administrator: TTLs: execution of AfterUpdate caused by: System.Exception: Record is read-only: Trigger.TTLs: line 7, column 9

 

trigger TTLs on Account (after update) { List<Account> udte = new List<Account>(); Integer accs; accs=[Select count() from Account where RecordType.Name='Student']; for(Account hr: trigger.old) { hr.Total_Students__c=accs; htoUpdte.add(hr); } }

 Yes I check the field level security, everything is editable about this field...

Where am I going wrong...

 

 

 

Is there a way to track what fired a trigger.  Example:  Was the trigger caused by the user updating the data, was the trigger caused by another trigger updating the data, or was the trigger caused by a batch process?

Hi all,

 

Wondered where would be the best place to test SOQL queries? I need to run some simple queries such as below [Select u.Contact.AccountId From User u where id = :uid and contactid != null]; and need to see the return results...

 

Many thanks, 

  • February 15, 2010
  • Like
  • 0

Here is a small sample of my code.  In the line that is commented out for the AddError (used for debugging) I am asking for the ID of the newFulfillment record I just added.  How do I get the ID?

 

 

                                   List<productProcesses__c> processes = [SELECT Name, predecessorStep__c, processStep__c, successorStep__c, workStepName__c FROM productProcesses__c];
                                   //for each one add to fulfillment and fulfillmentDependencies
                                   for (productProcesses__c pp: processes) {
                                       List<fulfillment__c> newFulfillment = new List<fulfillment__c>();
                                       List<fulfillmentDependencies__c> newDependencies = new List<fulfillmentDependencies__c>();
                                       if (pp.predecessorStep__c == 0) {
                                           newStatus = 'current';
                                       } else {
                                           newStatus = 'waiting';
                                       }
                                       newFulfillment.add( new fulfillment__c (Opportunity__c = o.Id , Status__c = newStatus, workStepName__c = pp.workStepName__c));
                                       try {
                                            insert newfulfillment;
                                            //o.AddError('ID: ' + newfulfillment.Id);
                                       }
                                       catch (DmlException de) {
                                           for (Integer I = 0; I < de.getNumDml(); i++) {
                                                o.addError(de.getDmlMessage(i));
                                           }
                                       }

The following trigger gives me this error:

 

Apex trigger LineItemTest caused an unexpected exception, contact your administrator: LineItemTest: execution of AfterInsert caused by: System.Exception: Record is read-only: Trigger.LineItemTest: line 3, column 9    

 

=============================

 

trigger LineItemTest on OpportunityLineItem (after insert) {
    for(OpportunityLineItem li: trigger.new) {
        li.Description = 'This is the replacement';
    }
}

I get the error:  maximum trigger depth exceeded .  I believe the system sees the OpportunityLineItem update as an update to the Opportunity object and creates an endless loop. This is the code from my trigger:

trigger OpportunityTest on Opportunity (after update) {
    for(Opportunity o : trigger.new) {
       List<OpportunityLineItem> newOrders = new List<OpportunityLineItem>();
       List<PricebookEntry> product = [SELECT ID, Name, UnitPrice FROM PricebookEntry WHERE ProductCode = 'GC1020' LIMIT 1];
       for (PricebookEntry pb: product) {
           //o.AddError('Product ' + pb.Name);
           newOrders.add ( new OpportunityLineItem (OpportunityID = o.ID, PricebookEntryID = pb.ID, Description = pb.Name, Quantity = 2, UnitPrice = pb.UnitPrice));
           insert newOrders;
       }
    }
}