+ Start a Discussion
Andrew GAndrew G 

Error in Insert Assigned Resource for Test Code

Hi
I'm doing a trigger that is triggered from the Assigned Resource.  The trigger works in the UI, however, I'm having an issue with the Test Code.

I receive an error:
FIELD_CUSTOM_VALIDATION_EXCEPTION, Cannot change status from New to Scheduled: []

Now, if i do the same from the UI, there is no error regarding the status change.  The status change is allowed in the FSL administration.  I can assign using the dispatcher console - all good.  And I can mimic the process i'm using in the test code in the UI (editing the SA directly) with out error.  
Wondering if any one has seen this error before?
Code is included below:
@isTest static void test_AssignedResource_Insert() {
		List<AssignedResource> toInsert = new List<AssignedResource>();

		//retrieve a service resource
		List<ServiceResource> listSR = new List<ServiceResource>([SELECT Id, Name FROM ServiceResource WHERE Name = 'Technician One']);
		ServiceResource sr1 = listSR[0];

		// retrieve the Service Appointment created by test data
		List<WorkOrder> workOrders = new List<WorkOrder>([SELECT Id FROM WorkOrder WHERE Subject ='Test Subject1']);
		List<Id> woIds = new List<Id>();
		for (WorkOrder wo : workOrders ) {
			woIds.add(wo.Id);
		}
		if (woIds.size() > 0 ) {
			List<ServiceAppointment> appts = new List<ServiceAppointment> ();
			appts = [SELECT Id FROM ServiceAppointment WHERE Work_Order__c IN :woIds];
			//for all the appts - should be one - create an assigned resource
			if(appts.size()>0) {
				for( ServiceAppointment sa : appts ) {
					sa.SchedStartTime = datetime.newInstance(2019, 4, 19, 11, 00, 0);
					sa.SchedEndTime = datetime.newInstance(2019, 4, 19, 11, 30, 0);

					AssignedResource ar = new AssignedResource(ServiceAppointmentId=sa.Id,ServiceResourceId=sr1.Id);
					toInsert.add(ar);
				}
				update appts;

				insert toInsert;

				List<ServiceAppointment> assignedSA = new List<ServiceAppointment>([SELECT Id,Technician_Name__c FROM ServiceAppointment WHERE Work_Order__c IN :woIds]);
				System.assertEquals(assignedSA.size(), 1);
				System.assertEquals(assignedSA[0].Technician_Name__c,sr1.Name);

			} else {

			}


		} else {
			//exception
			System.assertNotEquals(woIds.size(), 0);
		}


	}
the error occurs on the insert of the assigned resources
insert toInsert;
IF i change the code such that I manually do the status change in the code example:
sa.SchedStartTime = datetime.newInstance(2019, 4, 19, 11, 00, 0);
sa.SchedEndTime = datetime.newInstance(2019, 4, 19, 11, 30, 0);
sa.Status = 'Scheduled';
the error is returned for the update of the service appointments.
update appts;

Feed back greatly appreciated.

Andrew




 
Best Answer chosen by Andrew G
Andrew GAndrew G
OK,
So i discovered what the issue is and hopefully my explanation makes sense.  (or is 100% correctly explained).

With the FSL managed package, apparently the status transitions are retained in an object which lurks in the darkness of the back end and are not directly available.  I would suspect that the system logic is something like "if I can find a object record that explicitly states the transition is allowed, then allow the transition, otherwise return an error "not allowed".  

So these transitions exist as an object (not a system setting) and you need to use the SeeAllData tag in the test class.
@istest (SeeAllData=true)
The side effect of this is that I had to remove the @testsetup method I was using and move all my test data creation to a test helper class
@testSetup static void setupTestRecords() {  //removed - not compatiable with SeeAllData

Hope this helps others in their coding adventures.

Regards

Andrew


 

All Answers

Rajesh3699Rajesh3699
Hi,

Can you paste your validation rule. here..

Thank You,
Rajesh Adiga P.
Andrew GAndrew G
Hi Rajesh

There is no validation rule that I control in the Service Appointment that prevents the change of status from one to another.  However, I am using the FSL managed package which does have controls around the changes between Statuses.
Shown is the illistrative mapping of the allowed transitions
Allowed status changes in Service Appointment under FSL managed package

As noted, I can do the status change on the dispatcher console, and I can also mimic the behaviours of the test class in the UI, that is I can enter the scheduled times, save, and then change the status from New to Scheduled.  Or I can enter the scheduled times and then create an assigned resource in the related list.

Regards

Andrew
 
Andrew GAndrew G
OK,
So i discovered what the issue is and hopefully my explanation makes sense.  (or is 100% correctly explained).

With the FSL managed package, apparently the status transitions are retained in an object which lurks in the darkness of the back end and are not directly available.  I would suspect that the system logic is something like "if I can find a object record that explicitly states the transition is allowed, then allow the transition, otherwise return an error "not allowed".  

So these transitions exist as an object (not a system setting) and you need to use the SeeAllData tag in the test class.
@istest (SeeAllData=true)
The side effect of this is that I had to remove the @testsetup method I was using and move all my test data creation to a test helper class
@testSetup static void setupTestRecords() {  //removed - not compatiable with SeeAllData

Hope this helps others in their coding adventures.

Regards

Andrew


 
This was selected as the best answer
jjackson1.391016164401765E12jjackson1.391016164401765E12
Andrew, thank you for taking the time to explain this.  I am running into an issue with a unit test on some service appointment trigger code I wrote.  In my test I am unable to change an appointment status from Scheduled to Cannot Complete or Scheduled to In Progress.  It seems no status change made by my test code will work and it always throws this error, FIELD_CUSTOM_VALIDATION_EXCEPTION, Cannot change status from Scheduled to In Progress, for example.  There is no issue or rule violation error when changing an appointment status on a computer.  It only pops up when I am programatically doing it via a unit test.

It is troubling to me that now I have to change my test to "see all data" and create a dummy appointment that must live in our production org forever just to get the code coverage I need on one trigger method.  Salesforce really needs to do better to clean up some of this back end stuff.