function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
SelvaSelva 

before update trigger on account

Hi,
 
I am new to Apex trigger and Apex class.
I would like to know how to replace the old values with new values of Account object,if some criteria is met(for example, if the user who is updating the account is System administrator, update the old values(account name,account owner) with new values). I have to do it in the before update trigger. Do i need to create Apex class for updating the values?
 
my sample trigger code:
trigger tocAccountTrigger on Account (before update) {
    if (Trigger.isBefore) {
        if (Trigger.isUpdate) {
            for (Account a : Trigger.new) {
              // update the old values with the new values if the criteria met
            }
        }
    }
}

 
SelvaSelva
Please reply, as this is very urgent request
 
thanks
mani
micwamicwa
You do not need a class for updating the fields. But for testing your trigger you have to create a class with a testmethod.

To update fields, just set the field properties of your accounts:
Code:
for (Account a : Trigger.new) {
         if(...){
             a.Name = 'NewName';
             a.OwnerId = ...;
         }    
}
SelvaSelva
Hi Micwa,
 
Thanks for the hint. Actually, i need to update the old values with new values when the criteria met.
If the user performing the update on account object is system admin, then Account fields such as Name and Account Owner has to be replaced with the new values entered thru Account page.
You assigned the 'NewName' to a.Name.
How to fetch that new value which will be entered by user from account page and assign it to a.Name ?
 
regards
mani
 

 


Message Edited by Selva on 05-27-2008 04:45 AM

Message Edited by Selva on 05-27-2008 04:47 AM
micwamicwa
I don't know if I understand your question but you might have to work with Trigger.old and Trigger.new




Code:
Map<Id, Account> newAccountMap = Trigger.newMap;

for (Account oldAccount : Trigger.old) {
     Account newAccount = newAccountMap.get(a.Id);
    
     // with newAccount.name you can access data that were just entered
     //oldAccount is account before user edited something     
}

 

SelvaSelva
Wow.. this is what i expected Micwa! :-)
You had given me the solution for how to assign the old account values with the new account values.
I guess your method should be performing my requirement.
Let me try out and tell you the result.
 
thanks again
 
 
SelvaSelva

Can't we update the read-only value ?

 

micwamicwa
No you can't update those, thats why they are called "read-only". What exactly are you trying to do?
SelvaSelva

My requirment is below :

  • Create a before update trigger on account that will update the old  value with the new value when the criteria is met.
    • Fields for which old values will be replaced with the new values.

Name

Phone

Email

Fax

ShippingStreet

ShippingCity

ShippingState

ShippingPostal

ShippingCountry

Account Owner

Segment

 

      • Criteria for which the values have to be replaced
    • Current User performing the update is not “System Administrator”.

      Current Account has the Company Id populated and the company name is “IBM”.

    I tried the following code, but it failed since the values which i tried to replace are read-only.

     

    Code:
    trigger tocAccountTrigger on Account (before update) {
    Map<Id, Account> newAccountMap = Trigger.newMap;  
        if (Trigger.isBefore) {
            if (Trigger.isUpdate) {
            for (Profile p : [select name from Profile])
                for (Account a : Trigger.new) {
                    if (((a.IBM_Id__c == '' || a.IBM_Id__c == null) && a.tocSourceSystem__c=='IBM') ) {
                       a.IBM_Id__c.addError('IBM Id should be present');
                    }
                    for (Account oldAccount : Trigger.old) {
                     Account newAccount = newAccountMap.get(a.Id);
                     // with newAccount.name you can access data that were just entered
                     //oldAccount is account before user edited something
                     if ((newAccount.tocSourceSystem__c=='IBM')&&(newAccount.IBM_Id__c != '')&&(p.name != 'System Administrator')) {
                     // Replace the old account with the new account 
                       oldAccount.OwnerId = newAccount.OwnerId;
                       oldAccount.Name = newAccount.Name;
                       oldAccount.tfcmCustomerName__c = newAccount.tfcmCustomerName__c;
                       oldAccount.Phone = newAccount.Phone;
                       oldAccount.Fax = newAccount.Fax;
                       oldAccount.ShippingStreet = newAccount.ShippingStreet;
                       oldAccount.ShippingCity = newAccount.ShippingCity;
                       oldAccount.ShippingState = newAccount.ShippingState;
                       oldAccount.ShippingPostalCode = newAccount.ShippingPostalCode;
                       oldAccount.ShippingCountry = newAccount.ShippingCountry;
                       oldAccount.Segment__c = newAccount.Segment__c;
                     }
                    
                   }
    
                }
            }
        }
    }

     
    SelvaSelva

    Isn't it possible to  modify my sample code and meets the above requirement?

     

    tmatthiesentmatthiesen
    Trigger.old provides read-only access to the old version of the record.  You want to update Trigger.new - which is then passed into in update statement

    trigger tocAccountTrigger on Account (before update) {
                for (Account a : Trigger.new) {
                  // you can use the trigger.old for the comparison logic - but when updating values, leverage the trigger.new collection:
                       a.description = 'you can set this value';
           
    }
    }

    SelvaSelva

    Hi Sir,

    setting the other way around also doesn't work!! :-(

    newAccount.Name =  oldAccount.Name;

    Could you please modify the below code to meet my requirement?

    Code:
    trigger tocAccountTrigger on Account (before update) {
    Map<Id, Account> newAccountMap = Trigger.newMap;   
        if (Trigger.isBefore) {
            if (Trigger.isUpdate) {
            for (Profile p : [select name from Profile])
                for (Account a : Trigger.new) {
                    if (((a.IBM_Id__c == '' || a.IBM_Id__c == null) && a.tocSourceSystem__c=='IBM') ) {
                       a.IBM_Id__c.addError('IBM Id should be present');
                    }
    
                    for (Account oldAccount : Trigger.old) {
                     Account newAccount = newAccountMap.get(a.Id);
                     // with newAccount.name you can access data that were just entered
                     //oldAccount is account before user edited something
                     if ((newAccount.tocSourceSystem__c=='IBM')&&(newAccount.IBM_Id__c != '')&&(p.name != 'System Administrator')) {
                     // Replace the old account with the new account 
                        newAccount.OwnerId = oldAccount.OwnerId;
                       newAccount.Name =  oldAccount.Name;
                       newAccount.tfcmCustomerName__c = oldAccount.tfcmCustomerName__c;
                       newAccount.Phone = oldAccount.Phone;
                       newAccount.Fax = oldAccount.Fax;
                       newAccount.ShippingStreet = oldAccount.ShippingStreet;
                       newAccount.ShippingCity = oldAccount.ShippingCity;
                       newAccount.ShippingState = oldAccount.ShippingState;
                       newAccount.ShippingPostalCode = oldAccount.ShippingPostalCode;
                       newAccount.ShippingCountry = oldAccount.ShippingCountry;
                       newAccount.Segment__c = oldAccount.Segment__c;
                     }
                     
                   }
    
    
                }
            }
        }
    }

    The logic is that to replace the existing values for the mentioned fields with the new values that just entered by user(system admin)  for those corresponding fields, if the condition met. thats it..

    The above assignment doesn't update the old value with new value. Tried with opposite way, it does throw the exception saying Read-Only field can't be updated.

    Awaiting for the modified code which meets the requirement.


     

     

    SuperfellSuperfell
    I think you need to think about your requirements in reverse as the system will automatically update all the values based on those entered into the UI. I suspect what you really need to think about is the other case, what are you supposed to do when your criteria is not met, throw an error ?
    SelvaSelva

    Yes Simon, you are right!

    If the criteria(selected source system as IBM ,but IBM id is not entered by the user) is not met, then it should the error "IBM Id should be present". thats behaving as expected.

    If the above condition is met and the user updating the page is not system admin, then trigger shouldn't allow them to update the values with the error message saying that only system admin can update the values or something like that. Is it possible?

    I expecting my code to be modified with someone and it should be perfectly meet the requirement. As i am new to this apex, i don't think my code is 100% right.

    kindly check and give the update , if possible