• Mitchell McConnell
  • NEWBIE
  • 0 Points
  • Member since 2014

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

Yes, I know this is out there, but I still do not understand what is going on.  I am pretty new to SF, but have a lot of development experience in Java and other languages.

I am working in my free developer account, and wanted to create my first Apex code using a trigger.  Here is my business process.  I added a custom field to Account called Customer Level.  It is a picklist of "NORMAL" and "PREFERRED", with the default being NORMAL.   When the level is changed to PREFERRED, I want to create a trigger to create a new custom object called Preferred Customer Data, which has a one-to-one relationship with an Account (so there is a reference back to the account).  I put in another data field called Preferred Level which is a picklist of BRONZE, SILVER, and GOLD, with the default at creation being BRONZE.

So using the online Apex documentation, I dove in.

First, though, I created my objects and fields via the GUI.

I created a class with a static method that took an account ID and a level, and which creates the Preferred Customer object with the specified level.

public class UpdatePreferredCustomer{

    public static String CreatePreferredCustomerData(String accountId, String level) {
        Account acc = [select Id, Name, Customer_Level__c, AccountNumber
                       from Account where id=:accountId];
       
        if (acc == null) {
            System.debug('>>>> ERROR: could not find account');
        }
       
        System.Debug('>>>> Found account Id: ' + acc.Id + ', Name: ' + acc.Name);
        System.Debug('>>>> Customer level: ' + acc.Customer_Level__c);
       
        Preferred_Customer_Data__c pref = new Preferred_Customer_Data__c();
       
        pref.Name = 'Preferred data, test6';
        pref.Preferred_Level__c = level;
        pref.Account__c = accountId;
       
        // NOTE: the Preferred_Customer_Data custom object uses the Account's
        // AccountNumber as a unique external reference ID so we do not create
        // multiple records
       
        pref.Account_Number__c = acc.AccountNumber;
       
        upsert pref Account_Number__c;

        System.Debug('>>>> Upserted preferred customer level: ' + level);
       
        return 'SUCCESS';
    }
}

I next tested this method manually via the Developer Console and saw that it worked.

Next, I created a trigger for both after insert and after update, as it seemed like I need to cover both of those cases.

trigger MyAccountTrigger on Account (after update) {
   
    if (Trigger.isInsert) {
        System.debug('>>>> got insert trigger');
    } else {
        System.debug('>>>> got update trigger');
    }
   
    for (Account a : Trigger.new) {
        System.debug('>>>> Found account in trigger: ' + a.Name);
        String s = UpdatePreferredCustomer.CreatePreferredCustomerData(a.ID, 'BRONZE');
    }
}

Finally, I created a test class.

@isTest
public class UpdatePreferredCustomerTestClass{
    static testMethod void validateUpdatePreferredCustomer() {
        // Create a test account
       
        Account acc = new Account(Name='PreferredTestCustomer',
                                 AccountNumber='7275551212',
                                 Customer_Level__c='NORMAL');
       
        System.debug('>>>> Inserting account');
       
        // Insert
        insert acc;
       
        // Retrieve the new account
        acc = [SELECT ID FROM Account where Id =:acc.Id];
       
        // Now set the Customer Level.. this should trigger the creation
        // of the PreferredCustomer object via our trigger.
        
        acc.Customer_Level__c = 'PREFERRED';
        upsert acc;
       
        // Validate that the Preferred Customer Object got created, and
        // that the preferred level was set initially to BRONZE
        
        Preferred_Customer_Data__c pref = acc.Preferred_Customer_Data__r;
       
        System.debug('>>>> Get the Preferred Customer Object');
       
        System.debug('>>>> Preferred Customer level: ' + pref.Preferred_Level__c);
       
        System.assertEquals('BRONZE', pref.Preferred_Level__c);
       
    }
}

So, as my title says, when I run this, I get the aforementioned error.

The error line is pointing to this line in the test class:

     Preferred_Customer_Data__c pref = acc.Preferred_Customer_Data__r;

This made me think that there could be a race condition, because it *seems* as though the Preferred Customer Data
object *is* being created, yet it is not there when I go to look for it in the test class.

I would greatly appreciate any suggestions.  I am sure this is a simple issue that I am missing.

Mitch

Yes, I know this is out there, but I still do not understand what is going on.  I am pretty new to SF, but have a lot of development experience in Java and other languages.

I am working in my free developer account, and wanted to create my first Apex code using a trigger.  Here is my business process.  I added a custom field to Account called Customer Level.  It is a picklist of "NORMAL" and "PREFERRED", with the default being NORMAL.   When the level is changed to PREFERRED, I want to create a trigger to create a new custom object called Preferred Customer Data, which has a one-to-one relationship with an Account (so there is a reference back to the account).  I put in another data field called Preferred Level which is a picklist of BRONZE, SILVER, and GOLD, with the default at creation being BRONZE.

So using the online Apex documentation, I dove in.

First, though, I created my objects and fields via the GUI.

I created a class with a static method that took an account ID and a level, and which creates the Preferred Customer object with the specified level.

public class UpdatePreferredCustomer{

    public static String CreatePreferredCustomerData(String accountId, String level) {
        Account acc = [select Id, Name, Customer_Level__c, AccountNumber
                       from Account where id=:accountId];
       
        if (acc == null) {
            System.debug('>>>> ERROR: could not find account');
        }
       
        System.Debug('>>>> Found account Id: ' + acc.Id + ', Name: ' + acc.Name);
        System.Debug('>>>> Customer level: ' + acc.Customer_Level__c);
       
        Preferred_Customer_Data__c pref = new Preferred_Customer_Data__c();
       
        pref.Name = 'Preferred data, test6';
        pref.Preferred_Level__c = level;
        pref.Account__c = accountId;
       
        // NOTE: the Preferred_Customer_Data custom object uses the Account's
        // AccountNumber as a unique external reference ID so we do not create
        // multiple records
       
        pref.Account_Number__c = acc.AccountNumber;
       
        upsert pref Account_Number__c;

        System.Debug('>>>> Upserted preferred customer level: ' + level);
       
        return 'SUCCESS';
    }
}

I next tested this method manually via the Developer Console and saw that it worked.

Next, I created a trigger for both after insert and after update, as it seemed like I need to cover both of those cases.

trigger MyAccountTrigger on Account (after update) {
   
    if (Trigger.isInsert) {
        System.debug('>>>> got insert trigger');
    } else {
        System.debug('>>>> got update trigger');
    }
   
    for (Account a : Trigger.new) {
        System.debug('>>>> Found account in trigger: ' + a.Name);
        String s = UpdatePreferredCustomer.CreatePreferredCustomerData(a.ID, 'BRONZE');
    }
}

Finally, I created a test class.

@isTest
public class UpdatePreferredCustomerTestClass{
    static testMethod void validateUpdatePreferredCustomer() {
        // Create a test account
       
        Account acc = new Account(Name='PreferredTestCustomer',
                                 AccountNumber='7275551212',
                                 Customer_Level__c='NORMAL');
       
        System.debug('>>>> Inserting account');
       
        // Insert
        insert acc;
       
        // Retrieve the new account
        acc = [SELECT ID FROM Account where Id =:acc.Id];
       
        // Now set the Customer Level.. this should trigger the creation
        // of the PreferredCustomer object via our trigger.
        
        acc.Customer_Level__c = 'PREFERRED';
        upsert acc;
       
        // Validate that the Preferred Customer Object got created, and
        // that the preferred level was set initially to BRONZE
        
        Preferred_Customer_Data__c pref = acc.Preferred_Customer_Data__r;
       
        System.debug('>>>> Get the Preferred Customer Object');
       
        System.debug('>>>> Preferred Customer level: ' + pref.Preferred_Level__c);
       
        System.assertEquals('BRONZE', pref.Preferred_Level__c);
       
    }
}

So, as my title says, when I run this, I get the aforementioned error.

The error line is pointing to this line in the test class:

     Preferred_Customer_Data__c pref = acc.Preferred_Customer_Data__r;

This made me think that there could be a race condition, because it *seems* as though the Preferred Customer Data
object *is* being created, yet it is not there when I go to look for it in the test class.

I would greatly appreciate any suggestions.  I am sure this is a simple issue that I am missing.

Mitch