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
MrBurnz1980MrBurnz1980 

Trigger to update OwnerID to Customer Portal User

Hello..writing my first trigger. Could use your help :)

 

I have a custom object Financial__c that is a upload of payment information. I want to share this with Customer Portal users. The sharing is private since each customer can only see their payment. Also the upload has to happen using DataLoader.io which does not allow for OwnerID update. I need to update the OwnerId to the ID of the Customer Portal user so they can see it. As far I as know I can only do this with a trigger. Here is the simple trigger I've started with but getting an error. Appreciate your help!

 

trigger UpdateOwnerRecordBulk on Financial__c (before insert, before update) {

for (Financial__c oPayment : trigger.new) {

oPayment.OwnerID = [Select ID from USER WHERE ContactID=:oPayment.Home_Owner__c];

}

}

 

Error: Illegal assignment from LIST<User> to Id

Best Answer chosen by Admin (Salesforce Developers) 
MrBurnz1980MrBurnz1980

Yes thats it!! worked like a charm with 100% coverage..thank you thank you so much for your help. I learnt a lot. Final code for everyone. This trigger and test class changes the OwnerID of a custom object on create and update. Thanks to Sean Tan for his HUGE help in this. 

 

TEST CLASS

 

@isTest
private class UpdateOwnerRecordBulk4 {
    
    enum PortalType { CSPLiteUser, PowerPartner, PowerCustomerSuccess, CustomerSuccess }
    
    static testMethod void verifyOnwerIDChange() {
    
        RecordType[] accountRecordTypes = [ SELECT Id FROM RecordType WHERE Name = 'Properties' AND SObjectType = 'Account' ];
        RecordType[] contactRecordTypes = [ SELECT Id FROM RecordType WHERE Name = 'Resident' AND SObjectType = 'Contact' ];
                
        Id rtID1, rdID2;                        
        
        if (!accountRecordTypes.isEmpty())
        {
            rtID1 = accountRecordTypes[0].Id;
        }
        
        if (!contactRecordTypes.isEmpty())
        {
            rdID2 = contactRecordTypes[0].Id;
        }
        
        Account a = new Account(Name='My Test Account', RecordTypeID=rtID1);
        insert a;
        
        Contact c = new Contact(LastName='Test Contact', FirstName='Test', AccountId=a.Id, RecordTypeID=rdID2);
        insert c;
        
        User u = getPortalUser(PortalType.PowerCustomerSuccess, c, true);
        
        System.runAs(new User(Id=UserInfo.getUserId()))
        
        {
            // Perform our data preparation.        
            List<Financial__c> payments = new List<Financial__c>{};
            
         //   for(Integer i = 0; i < 200; i++)
         //   {            
                Financial__c pay = new Financial__c(Home_Owner__c = c.Id);                
                payments.add(pay);                
                
         //   }
            
            // Start the test, this changes governor limit context to             
            // that of trigger rather than test.             
            test.startTest();            
            // Insert the Account records that cause the trigger to execute.            
            insert payments; 
            // Stop the test, this changes limit context back to test from trigger.            
            test.stopTest();
            
            // Query the database for the newly inserted records.            
            List<Financial__c> insertedPayments = [SELECT ID, OwnerID             
                                                    FROM Financial__c            
                                                    WHERE Id IN :Payments];
            for(Financial__c p :insertedPayments)
            {                
                System.assertEquals(u.Id, p.OwnerId);            
            }
            
            
        }                        
    }
    
    public static User getPortalUser(PortalType portalType, Contact c, Boolean doInsert) 
    {        
        /* Make sure the running user has a role otherwise an exception 
        will be thrown. */       
        UserRole r = new UserRole(name = 'TEST ROLE');
        Database.insert(r);
        
        User userWithRole = new User(alias = 'hasrole', email='userwithrole@roletest1.com', userroleid = r.id,
        emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US', 
        localesidkey='en_US', profileid = UserInfo.getProfileId(), 
        timezonesidkey='America/Los_Angeles', username='userwithrole@testorg.com');        
        
        User pu;
        
        System.runAs(userWithRole) 
        {
            Profile p = [select id 
            from profile 
            where usertype = :portalType.name() 
            limit 1];   
            
            String testemail = 'puser000@amamama.com';
            pu = new User(profileId = p.id, username = testemail, email = testemail, 
            emailencodingkey = 'UTF-8', localesidkey = 'en_US', 
            languagelocalekey = 'en_US', timezonesidkey = 'America/Los_Angeles', 
            alias='cspu', lastname='lastname', contactId = c.id);
            
            Database.insert(pu);
        }
        
        return pu;        
    }
}

 

 

TRIGGER

 

trigger UpdateOwnerRecordBulk on Financial__c (before insert, before update) 
{
	Map<Id, User> userMap = new Map<Id, User>{};
	
	for (Financial__c oPayment : trigger.new) 
	{
		if (oPayment.Home_Owner__c != null)
		{
			userMap.put(oPayment.Home_Owner__c, null);
		}		
	}	
	
	for (User u : [Select ID, ContactID from USER WHERE ContactID IN :userMap.keySet()])
	{
		userMap.put(u.ContactID, u);
	}
	
	for (Financial__c oPayment : Trigger.new)
	{
		User u = userMap.get(oPayment.Home_Owner__c);
		
		if (u != null)
		{
			oPayment.OwnerId = u.Id;
		}
	}
}

 

 

 

 

All Answers

Sean TanSean Tan

You're trying to assign the list of users from the query to the OwnerId. General SOQL statements in Apex will return a list of SObjects (this can vary depending on the type of query). You also want to avoid querying in a loop. Try something like this:

 

trigger UpdateOwnerRecordBulk on Financial__c (before insert, before update) 
{
	Map<Id, User> userMap = new Map<Id, User>{};
	
	for (Financial__c oPayment : trigger.new) 
	{
		if (oPayment.Home_Owner__c != null)
		{
			userMap.put(oPayment.Home_Owner__c, null);
		}		
	}	
	
	for (User u : [Select ID, ContactID from USER WHERE ContactID IN :userMap.keySet()])
	{
		userMap.put(u.ContactID, u);
	}
	
	for (Financial__c oPayment : Trigger.new)
	{
		User u = userMap.get(oPayment.Home_Owner__c);
		
		if (u != null)
		{
			oPayment.OwnerId = u.Id;
		}
	}
}

 

MrBurnz1980MrBurnz1980

Thanks! that worked but having other issues now. Tried for a fewf hours to write a test method for the trigger to get 100% coverage but getting a really annoying error. Here is my entire code

 

 

 

 

trigger UpdateOwnerRecordBulk onFinancial__c (beforeinsert, beforeupdate

{

Map<Id, User> userMap = new Map<Id, User>{};

 

for (Financial__c oPayment : trigger.new

{

if (oPayment.Home_Owner__c != null)

{

userMap.put(oPayment.Home_Owner__c, null);

}

}

 

for (User u : [Select ID, ContactID from USER WHERE ContactID IN :userMap.keySet()])

{

userMap.put(u.ContactID, u);

}

 

for (Financial__c oPayment : Trigger.new)

{

User u = userMap.get(oPayment.Home_Owner__c);

 

if (u != null)

{

oPayment.OwnerId = u.Id;

}

}

}

 

@isTest

private class UpdateOwnerRecordBulk {

static testMethod void verifyOnwerIDChange(){

    // Perform our data preparation.

    List<Financial__c> payments = new List<Financial__c>{};

        

    for(Integer i = 0; i < 200; i++){

        Financial__c a = newFinancial__c(id);

        payments.add(a);

    }

 

    // Start the test, this changes governor limit context to 

    // that of trigger rather than test. 

    test.startTest();

 

    // Insert the Account records that cause the trigger to execute.

    insert payments; 

 

    // Stop the test, this changes limit context back to test from trigger.

    test.stopTest();

 

    // Query the database for the newly inserted records.

    List<Financial__c> insertedPayments = [SELECT ID, OwnerID 

                                      FROM Financial__c

                                      WHERE Id IN :Payments];

 

    // Assert that the Description fields contains the proper value now.

    for(Financial__c a : insertedPayments){

      insertedPayments.OwnerId = '005J00000013F86IAE'

    }

}

 

Getting the error Save errod: unexpected token:@  just before the @isTest line..what am I doing wrong? Also does the test method look ok? Thanks again!!

 

Sean TanSean Tan

Did you make a separate class file for the test class or did you try to put it in the same file as the trigger? If the latter try moving it to it's own test class.

 

In terms of the test class itself, you have a good portion of it there, the only problem is you're assuming data exists on the org (so if you were to deploy the test class to a different org it would fail). Nor are you assigning the Home_Owner__c value.

 

So I would do something like this:

 

@isTest(SeeAllData=false)
private class UpdateOwnerRecordBulk {
    
    static testMethod void verifyOnwerIDChange() {
        
        Account a = new Account(Name='My Test Account');
        insert a;
        
        Contact c = new Contact(LastName='Test Contact', FirstName='Test', AccountId=a.Id);
        insert c;
        
        User u = [ select Username, FirstName, LastName, Email, Alias, Department, MobilePhone, Title, TimeZoneSidKey, LocaleSidKey, LanguageLocaleKey, EmailEncodingKey, ProfileId, UserRoleId FROM User WHERE Id = :UserInfo.getUserId() ];
        //Clone but get rid of the Id
        u = u.clone(false);        
        u.Username = 'testuser1111@testuser.com';
        u.IsActive = true;
        u.ContactID = c.Id;
        
        //Inserting the test user
        System.runAs(u)
        {
            // Perform our data preparation.        
            List<Financial__c> payments = new List<Financial__c>{};
            
            for(Integer i = 0; i < 200; i++)
            {            
                Financial__c a = new Financial__c(Home_Owner__c = c.Id);                
                payments.add(a);                
            }
                                    
            // Start the test, this changes governor limit context to             
            // that of trigger rather than test.             
            test.startTest();            
            // Insert the Account records that cause the trigger to execute.            
            insert payments;
            // Stop the test, this changes limit context back to test from trigger.            
            test.stopTest();
                        
            // Query the database for the newly inserted records.            
            List<Financial__c> insertedPayments = [SELECT ID, OwnerID             
                                                    FROM Financial__c            
                                                    WHERE Id IN :Payments];
            
            // Assert that the Description fields contains the proper value now.
            for(Financial__c a : insertedPayments)
            {                
                System.assertEquals(u.Id, insertedPayments.OwnerId);            
            }
        }                        
    }
}

 This may still fail if some required fields are missing for the insert of records... but it should get you in the right direction.

MrBurnz1980MrBurnz1980

Thanks that definetly helped. Here is my test class so far. 

 

@isTest
private class UpdateOwnerRecordBulk {
 
static testMethod void verifyOnwerIDChange(){
 
Id rtID1= [SELECT Id from RecordType where Name='Properties'].Id;
Id rtID2= [SELECT Id from RecordType where Name='Resident'].Id;
 
Account a = new Account(Name='My Test Account', RecordTypeID=rtID1);
        insert a;
    
    Contact c = new Contact(LastName='Test Contact', FirstName='Test', AccountId=a.Id, RecordTypeID=rtID2);
        insert c;
       
     User u = [ select Username, FirstName, LastName, Email, Alias, Department, 
     MobilePhone, Title, TimeZoneSidKey, LocaleSidKey, LanguageLocaleKey, EmailEncodingKey, ProfileId, UserRoleId FROM User WHERE Id = :UserInfo.getUserId() ];
    
     //Clone but get rid of the Id
        u = u.clone(false);        
        u.Username = 'testuser1111@testuser.com';
        u.IsActive = true;
        u.ContactID = c.Id;
        
    //Inserting the test user
        System.runAs(u)
        {
            // Perform our data preparation.        
            List<Financial__c> payments = new List<Financial__c>{};
            
            for(Integer i = 0; i < 200; i++)
            {            
                Financial__c p = new Financial__c(Home_Owner__c = c.Id);                
                payments.add(p);                
            }
                                    
            // Start the test, this changes governor limit context to             
            // that of trigger rather than test.             
            test.startTest();            
            // Insert the Account records that cause the trigger to execute.            
            insert payments; 
            // Stop the test, this changes limit context back to test from trigger.            
            test.stopTest();
                        
            // Query the database for the newly inserted records.            
            List<Financial__c> insertedPayments = [SELECT ID, OwnerID             
                                                    FROM Financial__c            
                                                    WHERE Id IN :Payments];
            
            /*
            for(Financial__c p :insertedPayments)
            {                
                insertedPayments.OwnerId = u.Id;            
            }
            */
        }                        
    }
}

 Error I am getting is on line 43 and the debug log says 

FIELD_INTEGRITY_EXCEPTION, only portal users can be associated to a contact: []

 

which makes sense since the contact user is not a portal user. So how do we enable the contact as the portal user in the code? 

 

Thanks so much for your help so far!

MrBurnz1980MrBurnz1980

Reading this article and it looks like it could help http://wiki.developerforce.com/page/Apex_Testing_with_RunAs

Sean TanSean Tan

Based off the article try this type of variation:

 

@isTest
private class UpdateOwnerRecordBulk {
    
    enum PortalType { CSPLiteUser, PowerPartner, PowerCustomerSuccess, CustomerSuccess }
    
    static testMethod void verifyOnwerIDChange(){
        
        Id rtID1= [SELECT Id from RecordType where Name='Properties'].Id;
        Id rtID2= [SELECT Id from RecordType where Name='Resident'].Id;
        
        Account a = new Account(Name='My Test Account', RecordTypeID=rtID1);
        insert a;
        
        Contact c = new Contact(LastName='Test Contact', FirstName='Test', AccountId=a.Id, RecordTypeID=rtID2);
        insert c;
        
        User u = getPortalUser(PortalType.PowerPartner, c, true);
                
        System.runAs(new User(Id=UserInfo.getUserId()))
        {
            // Perform our data preparation.        
            List<Financial__c> payments = new List<Financial__c>{};
            
            for(Integer i = 0; i < 200; i++)
            {            
                Financial__c p = new Financial__c(Home_Owner__c = c.Id);                
                payments.add(p);                
            }
            
            // Start the test, this changes governor limit context to             
            // that of trigger rather than test.             
            test.startTest();            
            // Insert the Account records that cause the trigger to execute.            
            insert payments;
            // Stop the test, this changes limit context back to test from trigger.            
            test.stopTest();
            
            // Query the database for the newly inserted records.            
            List<Financial__c> insertedPayments = [SELECT ID, OwnerID             
            FROM Financial__c            
            WHERE Id IN :Payments];
            
            /*
                for(Financial__c p :insertedPayments)
                {                
                insertedPayments.OwnerId = u.Id;            
                }
            */
        }                        
    }
        
    public static User getPortalUser(PortalType portalType, Contact c, Boolean doInsert)
    {        
        /* Make sure the running user has a role otherwise an exception
        will be thrown. */       
        UserRole r = new UserRole(name = 'TEST ROLE');
        Database.insert(r);
        
        User userWithRole = new User(alias = 'hasrole', email='userwithrole@roletest1.com', userroleid = r.id,
        emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US',
        localesidkey='en_US', profileid = UserInfo.getProfileId(),
        timezonesidkey='America/Los_Angeles', username='userwithrole@testorg.com');        
        
        User pu;
        
        System.runAs(userWithRole)
        {
            Profile p = [select id
            from profile
            where usertype = :portalType.name()
            limit 1];   
            
            String testemail = 'puser000@amamama.com';
            pu = new User(profileId = p.id, username = testemail, email = testemail,
            emailencodingkey = 'UTF-8', localesidkey = 'en_US',
            languagelocalekey = 'en_US', timezonesidkey = 'America/Los_Angeles',
            alias='cspu', lastname='lastname', contactId = c.id);
            
            Database.insert(pu);
        }
        
        return pu;        
    }
}

 

MrBurnz1980MrBurnz1980

Thanks again..getting very close..now I have the error save error initial term of field expression must be a concrete sobject LIST<Financial__c>

 

I think the issue is with this for statement at the very end

 

List<Financial__c> insertedPayments = [SELECT ID, OwnerID             
            FROM Financial__c            
            WHERE Id IN :Payments];
 for(Financial__c p :insertedPayments)
                {                
                insertedPayments.OwnerId=u.Id;            
                }

I

 

 

since its a list..should it be in some other format? Thanks.

 

 

Sean TanSean Tan

Are you trying to make sure the owner id is the same as the user id?

 

Then you should use an assert statement. The reason for the error is you're assigning the user id to an owner Id property on the List object not the looped record.

 

Try this for the loop:

 

List<Financial__c> insertedPayments = [SELECT ID, OwnerID             
                                                    FROM Financial__c            
                                                    WHERE Id IN :Payments];
for(Financial__c p :insertedPayments)
{                
     System.assertEquals(u.Id, p.OwnerId);            
}

 

MrBurnz1980MrBurnz1980

Thanks Sean..that got rid of that error but now I get 

FATAL_ERROR|System.QueryException: List has no rows for assignment to SObject

 

Here is the entire code so far. 

 

@isTest
private class UpdateOwnerRecordBulk3 {
    
    enum PortalType { CSPLiteUser, PowerPartner, PowerCustomerSuccess, CustomerSuccess }
    
    static testMethod void verifyOnwerIDChange(){
        
        Id rtID1= [SELECT Id from RecordType where Name='Properties'].Id;
        Id rtID2= [SELECT Id from RecordType where Name='Resident'].Id;
        
        Account a = new Account(Name='My Test Account', RecordTypeID=rtID1);
        insert a;
        
        Contact c = new Contact(LastName='Test Contact', FirstName='Test', AccountId=a.Id, RecordTypeID=rtID2);
        insert c;
        
        User u = getPortalUser(PortalType.PowerPartner, c, true);
                
        System.runAs(new User(Id=UserInfo.getUserId()))

        {
            // Perform our data preparation.        
            List<Financial__c> payments = new List<Financial__c>{};
            
            for(Integer i = 0; i < 200; i++)
            {            
                Financial__c p = new Financial__c(Home_Owner__c = c.Id);                
                payments.add(p);                

            }
            
            // Start the test, this changes governor limit context to             
            // that of trigger rather than test.             
            test.startTest();            
            // Insert the Account records that cause the trigger to execute.            
            insert payments; 
            // Stop the test, this changes limit context back to test from trigger.            
            test.stopTest();
            
            // Query the database for the newly inserted records.            
            List<Financial__c> insertedPayments = [SELECT ID, OwnerID             
                                                    FROM Financial__c            
                                                    WHERE Id IN :Payments];
			for(Financial__c p :insertedPayments)
			{                
    		 System.assertEquals(u.Id, p.OwnerId);            
			}

           
        }                        
    }
        
    public static User getPortalUser(PortalType portalType, Contact c, Boolean doInsert) 
    {        
        /* Make sure the running user has a role otherwise an exception 
        will be thrown. */       
        UserRole r = new UserRole(name = 'TEST ROLE');
        Database.insert(r);
        
        User userWithRole = new User(alias = 'hasrole', email='userwithrole@roletest1.com', userroleid = r.id,
        emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US', 
        localesidkey='en_US', profileid = UserInfo.getProfileId(), 
        timezonesidkey='America/Los_Angeles', username='userwithrole@testorg.com');        
        
        User pu;
        
        System.runAs(userWithRole) 
        {
            Profile p = [select id 
            from profile 
            where usertype = :portalType.name() 
            limit 1];   
            
            String testemail = 'puser000@amamama.com';
            pu = new User(profileId = p.id, username = testemail, email = testemail, 
            emailencodingkey = 'UTF-8', localesidkey = 'en_US', 
            languagelocalekey = 'en_US', timezonesidkey = 'America/Los_Angeles', 
            alias='cspu', lastname='lastname', contactId = c.id);
            
            Database.insert(pu);
        }
        
        return pu;        
    }
}

 

Sean TanSean Tan

When you post the errors can you post the full trace (including the line numbers). It helps to pinpoint issues... In terms of the problem I'm guessing it is due to the following lines:

 

Id rtID1= [SELECT Id from RecordType where Name='Properties'].Id;
Id rtID2= [SELECT Id from RecordType where Name='Resident'].Id;

You can try changing it to something like the following:

 

@isTest
private class UpdateOwnerRecordBulk3 {
    
    enum PortalType { CSPLiteUser, PowerPartner, PowerCustomerSuccess, CustomerSuccess }
    
    static testMethod void verifyOnwerIDChange() {
    
        RecordType[] accountRecordTypes = [ SELECT Id FROM RecordType WHERE Name = 'Properties' AND SObjectType = 'Account' ];
        RecordType[] contactRecordTypes = [ SELECT Id FROM RecordType WHERE Name = 'Resident' AND SObjectType = 'Contact' ];
                
        Id rtID1, rdID2;                        
        
        if (!accountRecordTypes.isEmpty())
        {
            rtID1 = accountRecordsTypes[0].Id;
        }
        
        if (!contactRecordTypes.isEmpty())
        {
            rtID2 = contactRecordTypes[0].Id;
        }
        
        Account a = new Account(Name='My Test Account', RecordTypeID=rtID1);
        insert a;
        
        Contact c = new Contact(LastName='Test Contact', FirstName='Test', AccountId=a.Id, RecordTypeID=rtID2);
        insert c;
        
        User u = getPortalUser(PortalType.PowerPartner, c, true);
        
        System.runAs(new User(Id=UserInfo.getUserId()))
        
        {
            // Perform our data preparation.        
            List<Financial__c> payments = new List<Financial__c>{};
            
            for(Integer i = 0; i < 200; i++)
            {            
                Financial__c p = new Financial__c(Home_Owner__c = c.Id);                
                payments.add(p);                
                
            }
            
            // Start the test, this changes governor limit context to             
            // that of trigger rather than test.             
            test.startTest();            
            // Insert the Account records that cause the trigger to execute.            
            insert payments;
            // Stop the test, this changes limit context back to test from trigger.            
            test.stopTest();
            
            // Query the database for the newly inserted records.            
            List<Financial__c> insertedPayments = [SELECT ID, OwnerID             
                                                    FROM Financial__c            
                                                    WHERE Id IN :Payments];
            for(Financial__c p :insertedPayments)
            {                
                System.assertEquals(u.Id, p.OwnerId);            
            }
            
            
        }                        
    }
    
    public static User getPortalUser(PortalType portalType, Contact c, Boolean doInsert)
    {        
        /* Make sure the running user has a role otherwise an exception
        will be thrown. */       
        UserRole r = new UserRole(name = 'TEST ROLE');
        Database.insert(r);
        
        User userWithRole = new User(alias = 'hasrole', email='userwithrole@roletest1.com', userroleid = r.id,
        emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US',
        localesidkey='en_US', profileid = UserInfo.getProfileId(),
        timezonesidkey='America/Los_Angeles', username='userwithrole@testorg.com');        
        
        User pu;
        
        System.runAs(userWithRole)
        {
            Profile p = [select id
            from profile
            where usertype = :portalType.name()
            limit 1];   
            
            String testemail = 'puser000@amamama.com';
            pu = new User(profileId = p.id, username = testemail, email = testemail,
            emailencodingkey = 'UTF-8', localesidkey = 'en_US',
            languagelocalekey = 'en_US', timezonesidkey = 'America/Los_Angeles',
            alias='cspu', lastname='lastname', contactId = c.id);
            
            Database.insert(pu);
        }
        
        return pu;        
    }
}

 

MrBurnz1980MrBurnz1980

Here is the entire Debug Log..Not suire if it's the ID rt1D1 line causing the error. Thanks.

 

Debug Log:

27.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;VALIDATION,INFO;WORKFLOW,INFO
08:16:15.685 (685119000)|EXECUTION_STARTED
08:16:15.685 (685160000)|CODE_UNIT_STARTED|[EXTERNAL]|01pJ00000009mEV|UpdateOwnerRecordBulk3.verifyOnwerIDChange
08:16:15.685 (685657000)|METHOD_ENTRY|[2]|01pJ00000009mEV|UpdateOwnerRecordBulk3.UpdateOwnerRecordBulk3()
08:16:15.685 (685672000)|METHOD_EXIT|[2]|UpdateOwnerRecordBulk3
08:16:15.686 (686052000)|SOQL_EXECUTE_BEGIN|[8]|Aggregations:0|select Id from RecordType where Name = 'Properties'
08:16:15.700 (700769000)|SOQL_EXECUTE_END|[8]|Rows:1
08:16:15.701 (701320000)|SOQL_EXECUTE_BEGIN|[9]|Aggregations:0|select Id from RecordType where Name = 'Resident'
08:16:15.706 (706560000)|SOQL_EXECUTE_END|[9]|Rows:1
08:16:15.706 (706828000)|DML_BEGIN|[12]|Op:Insert|Type:Account|Rows:1
08:16:16.229 (1229606000)|DML_END|[12]
08:16:16.230 (1230102000)|DML_BEGIN|[15]|Op:Insert|Type:Contact|Rows:1
08:16:16.314 (1314438000)|DML_END|[15]
08:16:16.314 (1314729000)|METHOD_ENTRY|[17]|01pJ00000009mEV|UpdateOwnerRecordBulk3.getPortalUser(UpdateOwnerRecordBulk3.PortalType, Contact, Boolean)
08:16:16.315 (1315105000)|DML_BEGIN|[58]|Op:Insert|Type:UserRole|Rows:1
08:16:16.879 (1879240000)|DML_END|[58]
08:16:16.879 (1879857000)|DML_BEGIN|[60]|Op:Insert|Type:User|Rows:1
08:16:17.781 (2781628000)|DML_END|[60]
08:16:17.849 (2849745000)|METHOD_ENTRY|[69]|01pJ00000009mEV|UpdateOwnerRecordBulk3.PortalType.name()
08:16:17.849 (2849801000)|METHOD_EXIT|[69]|01pJ00000009mEV|UpdateOwnerRecordBulk3.PortalType.name()
08:16:17.849 (2849955000)|SOQL_EXECUTE_BEGIN|[69]|Aggregations:0|select id from profile where usertype = :tmpVar1 limit 1
08:16:17.876 (2876396000)|SOQL_EXECUTE_END|[69]|Rows:0
08:16:17.909 (2909506000)|METHOD_EXIT|[17]|01pJ00000009mEV|UpdateOwnerRecordBulk3.getPortalUser(UpdateOwnerRecordBulk3.PortalType, Contact, Boolean)
08:16:17.909 (2909611000)|FATAL_ERROR|System.QueryException: List has no rows for assignment to SObject

Class.UpdateOwnerRecordBulk3.getPortalUser: line 69, column 1
Class.UpdateOwnerRecordBulk3.verifyOnwerIDChange: line 17, column 1
08:16:17.909 (2909633000)|FATAL_ERROR|System.QueryException: List has no rows for assignment to SObject

Class.UpdateOwnerRecordBulk3.getPortalUser: line 69, column 1
Class.UpdateOwnerRecordBulk3.verifyOnwerIDChange: line 17, column 1
08:16:17.775 (2909659000)|CUMULATIVE_LIMIT_USAGE
08:16:17.775|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 3 out of 100
  Number of query rows: 2 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 5 out of 150
  Number of DML rows: 5 out of 10000
  Number of code statements: 12 out of 200000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 10
  Number of Email Invocations: 0 out of 10
  Number of fields describes: 0 out of 100
  Number of record type describes: 0 out of 100
  Number of child relationships describes: 0 out of 100
  Number of picklist describes: 0 out of 100
  Number of future calls: 0 out of 10

08:16:17.775|CUMULATIVE_LIMIT_USAGE_END

08:16:17.909 (2909694000)|CODE_UNIT_FINISHED|UpdateOwnerRecordBulk3.verifyOnwerIDChange
08:16:17.909 (2909706000)|EXECUTION_FINISHED

 

Sean TanSean Tan

Ok so it's this:

 

Profile p = [select id
            from profile
            where usertype = :portalType.name()
            limit 1];  

 

It's not returning any profile for that particular portal type... What type's of portal user type's are on the org? Unfortunately you can't insert these types in the test method so you have to assume that data exists. If you know which Profile type exists you can change the line here:

 

User u = getPortalUser(PortalType.PowerPartner, c, true);

 

And change the PortalType.PowerPartner to one of the following:

 

  • CSPLiteUser
  • PowerPartner
  • PowerCustomerSuccess
  • CustomerSuccess
MrBurnz1980MrBurnz1980

Yes thats it!! worked like a charm with 100% coverage..thank you thank you so much for your help. I learnt a lot. Final code for everyone. This trigger and test class changes the OwnerID of a custom object on create and update. Thanks to Sean Tan for his HUGE help in this. 

 

TEST CLASS

 

@isTest
private class UpdateOwnerRecordBulk4 {
    
    enum PortalType { CSPLiteUser, PowerPartner, PowerCustomerSuccess, CustomerSuccess }
    
    static testMethod void verifyOnwerIDChange() {
    
        RecordType[] accountRecordTypes = [ SELECT Id FROM RecordType WHERE Name = 'Properties' AND SObjectType = 'Account' ];
        RecordType[] contactRecordTypes = [ SELECT Id FROM RecordType WHERE Name = 'Resident' AND SObjectType = 'Contact' ];
                
        Id rtID1, rdID2;                        
        
        if (!accountRecordTypes.isEmpty())
        {
            rtID1 = accountRecordTypes[0].Id;
        }
        
        if (!contactRecordTypes.isEmpty())
        {
            rdID2 = contactRecordTypes[0].Id;
        }
        
        Account a = new Account(Name='My Test Account', RecordTypeID=rtID1);
        insert a;
        
        Contact c = new Contact(LastName='Test Contact', FirstName='Test', AccountId=a.Id, RecordTypeID=rdID2);
        insert c;
        
        User u = getPortalUser(PortalType.PowerCustomerSuccess, c, true);
        
        System.runAs(new User(Id=UserInfo.getUserId()))
        
        {
            // Perform our data preparation.        
            List<Financial__c> payments = new List<Financial__c>{};
            
         //   for(Integer i = 0; i < 200; i++)
         //   {            
                Financial__c pay = new Financial__c(Home_Owner__c = c.Id);                
                payments.add(pay);                
                
         //   }
            
            // Start the test, this changes governor limit context to             
            // that of trigger rather than test.             
            test.startTest();            
            // Insert the Account records that cause the trigger to execute.            
            insert payments; 
            // Stop the test, this changes limit context back to test from trigger.            
            test.stopTest();
            
            // Query the database for the newly inserted records.            
            List<Financial__c> insertedPayments = [SELECT ID, OwnerID             
                                                    FROM Financial__c            
                                                    WHERE Id IN :Payments];
            for(Financial__c p :insertedPayments)
            {                
                System.assertEquals(u.Id, p.OwnerId);            
            }
            
            
        }                        
    }
    
    public static User getPortalUser(PortalType portalType, Contact c, Boolean doInsert) 
    {        
        /* Make sure the running user has a role otherwise an exception 
        will be thrown. */       
        UserRole r = new UserRole(name = 'TEST ROLE');
        Database.insert(r);
        
        User userWithRole = new User(alias = 'hasrole', email='userwithrole@roletest1.com', userroleid = r.id,
        emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US', 
        localesidkey='en_US', profileid = UserInfo.getProfileId(), 
        timezonesidkey='America/Los_Angeles', username='userwithrole@testorg.com');        
        
        User pu;
        
        System.runAs(userWithRole) 
        {
            Profile p = [select id 
            from profile 
            where usertype = :portalType.name() 
            limit 1];   
            
            String testemail = 'puser000@amamama.com';
            pu = new User(profileId = p.id, username = testemail, email = testemail, 
            emailencodingkey = 'UTF-8', localesidkey = 'en_US', 
            languagelocalekey = 'en_US', timezonesidkey = 'America/Los_Angeles', 
            alias='cspu', lastname='lastname', contactId = c.id);
            
            Database.insert(pu);
        }
        
        return pu;        
    }
}

 

 

TRIGGER

 

trigger UpdateOwnerRecordBulk on Financial__c (before insert, before update) 
{
	Map<Id, User> userMap = new Map<Id, User>{};
	
	for (Financial__c oPayment : trigger.new) 
	{
		if (oPayment.Home_Owner__c != null)
		{
			userMap.put(oPayment.Home_Owner__c, null);
		}		
	}	
	
	for (User u : [Select ID, ContactID from USER WHERE ContactID IN :userMap.keySet()])
	{
		userMap.put(u.ContactID, u);
	}
	
	for (Financial__c oPayment : Trigger.new)
	{
		User u = userMap.get(oPayment.Home_Owner__c);
		
		if (u != null)
		{
			oPayment.OwnerId = u.Id;
		}
	}
}

 

 

 

 

This was selected as the best answer
MrBurnz1980MrBurnz1980

The trigger and class I posted work great but I tried to create a package and getting this DML exception error on the Class. Has anyone seen this?

 

 

System.DmlException: Insert failed. First exception on row 0; first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): UserRole, original object: Account: []