You need to sign in to do that
Don't have an account?
Error with apex class called 'tom_test_cancellation' from salesforce time-off manager app
Hello,
I need help tracking down what is causing this error. It seems to be a read permission error, but everyone has read permission so I do not understand what does not have read permission.
Method Name:
tom_test_cancellation.test_cancellation
Message:
System.DmlException: Update failed. First exception on row 0 with id a0M50000000yOJ4EAM; first error: TRANSFER_REQUIRES_READ, The new owner must have read permission
Stack Trace:
Class.ptoPackage.cancel_request_without_commit: line 444, column 3 Class.tom_test_cancellation.test_cancellation: line 53, column 6 External entry point
public class ptoPackage { public static void cancel_request_without_commit(Id request_id) { Time_Off_Request__c[] tors = [select Id, Status__c from Time_Off_Request__c where (Id = :request_id) and (IsDeleted = false)]; if (tors.size() == 0) { throw new Time_Off_Exception('There is no Time Off Request with ID \'' + request_id + '\', so it cannot be canceled.'); } System.assert(tors.size() == 1); if ((tors[0].Status__c != 'Approved') && (tors[0].Status__c != 'Rejected') && (tors[0].Status__c != 'Requires Re-Approval')) { throw new Time_Off_Exception('A Time Off Request cannot be closed if it is in the ' + tors[0].Status__c + ' state.'); } tors[0].Status__c = 'Canceled'; update tors; } }
As far as I can tell the method 'cancel_request_without_commit' sets
status of the current 'Time_Off_Request__c' to 'Canceled' if the status
is 'Approved','Rejected', or 'Requires Re-Approval', else it throws an
error message.
I know in the time-off manager pto request
process the 'Time_Off_Request__c' record ownership changes. It changes
to the designated 'approval process' user when the record is in the
approval process and the status is 'pending approval'. When the status
is 'approved' the owner of the 'Time_Off_Request__c' record is the
'Time_Off_Manager_Payroll' queue as a way of locking them down. When
you cancel a 'Time_Off_Request__c' the owner goes back to the
'Time_Off_Request__c' record creator if it is different. So I think I
understand how the error message relates to transfering ownership of
record.
I check the objects for the time off manager and every
user profile has at least read permission for all objects. Its setup as
suggested in the customization guide. For most users they have more
than the minimum permission, but every users profile meets the minimum.
Is there something else I should check?
Do you think its safe to
assume since this error does not happen in the sandbox with the exact
same configuration setup. In a configuration only sandbox with no data
records. That the problem is with the 'Time_Off_Request__c' data
records in production that the 'cancel_request_without_commit' can runa
against? In other words its the data not the configuration?
Thank you
In case anyone visists this post I wanted to post what the cause of the problem was.
I dont know why all of a sudden the original developers test class is grabbing invalid users to test with but that was the problem. You can see my comment below for the 'users' collection.
public static Map<String, User> get_test_user_ids() { Map<String, User> result = new Map<String, User>(); User[] users = [select Id, Employee_Number__c, Manager_PTO__c, LastName from User where isActive = true // walter@adicio change to limit to only standard userType // we started receiving test failures for TOR request ownership // transfer, and determined the broad criteria of just grabbing // an active user technically can grab a customer portal user, // force.com sites guest user, and so on, basically any user and UserType = 'Standard'limit 3]; if (users.size() != 3) { throw new ptoPackage.Time_Off_Exception('There must be at least 3 users in order to test the Time Off Manager application.'); } users[0].FirstName = 'Test'; users[0].LastName = 'Manager'; users[0].Manager_PTO__c = null; users[0].Employee_Number__c = 'TEST 1'; users[1].FirstName = 'Test'; users[1].LastName = 'Subordinate'; users[1].Manager_PTO__c = users[0].Id; users[1].Employee_Number__c = 'TEST 2'; users[2].FirstName = 'Test'; users[2].LastName = 'Subordinate2'; users[2].Manager_PTO__c = users[0].Id; users[2].Employee_Number__c = 'TEST 3'; update users; Set<Id> user_ids = new Set<Id>(); for (User user : users) { user_ids.add(user.Id); } System.assert(user_ids.size() == 3); Time_Off_Info__c[] old_tois = [select Id from Time_Off_Info__c where User__c in :user_ids]; if ((old_tois != null) && (old_tois.size() > 0)) { delete old_tois; } Time_Off_Info__c[] new_tois = new Time_Off_Info__c[0]; for (User user : users) { Time_Off_Info__c new_toi = ptoPackage.build_time_off_info(user, 0, 'TEST'); new_tois.add(new_toi); result.put(user.LastName, user); if (user.LastName == 'Manager') { System.assert(user.Manager_PTO__c == null); } else { System.assert(user.Manager_PTO__c != null); } } insert new_tois; return result; }
All Answers
In case anyone visists this post I wanted to post what the cause of the problem was.
I dont know why all of a sudden the original developers test class is grabbing invalid users to test with but that was the problem. You can see my comment below for the 'users' collection.
public static Map<String, User> get_test_user_ids() { Map<String, User> result = new Map<String, User>(); User[] users = [select Id, Employee_Number__c, Manager_PTO__c, LastName from User where isActive = true // walter@adicio change to limit to only standard userType // we started receiving test failures for TOR request ownership // transfer, and determined the broad criteria of just grabbing // an active user technically can grab a customer portal user, // force.com sites guest user, and so on, basically any user and UserType = 'Standard'limit 3]; if (users.size() != 3) { throw new ptoPackage.Time_Off_Exception('There must be at least 3 users in order to test the Time Off Manager application.'); } users[0].FirstName = 'Test'; users[0].LastName = 'Manager'; users[0].Manager_PTO__c = null; users[0].Employee_Number__c = 'TEST 1'; users[1].FirstName = 'Test'; users[1].LastName = 'Subordinate'; users[1].Manager_PTO__c = users[0].Id; users[1].Employee_Number__c = 'TEST 2'; users[2].FirstName = 'Test'; users[2].LastName = 'Subordinate2'; users[2].Manager_PTO__c = users[0].Id; users[2].Employee_Number__c = 'TEST 3'; update users; Set<Id> user_ids = new Set<Id>(); for (User user : users) { user_ids.add(user.Id); } System.assert(user_ids.size() == 3); Time_Off_Info__c[] old_tois = [select Id from Time_Off_Info__c where User__c in :user_ids]; if ((old_tois != null) && (old_tois.size() > 0)) { delete old_tois; } Time_Off_Info__c[] new_tois = new Time_Off_Info__c[0]; for (User user : users) { Time_Off_Info__c new_toi = ptoPackage.build_time_off_info(user, 0, 'TEST'); new_tois.add(new_toi); result.put(user.LastName, user); if (user.LastName == 'Manager') { System.assert(user.Manager_PTO__c == null); } else { System.assert(user.Manager_PTO__c != null); } } insert new_tois; return result; }
thanks in advance
Regards
Deepak