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
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.  
Dobias van Buuren 5Dobias van Buuren 5
Hi, there is also another solution that does not require the SeeAllData.
Do something like this in your TestSetup:
 
FSL.GlobalAPIS.addStatusTransition('New', 'Scheduled');

Now your tests will run as expected.
Matt Scholl 15Matt Scholl 15
Thanks Dobias! Exactly what I was looking for! Cheers!
Ashish Yaduka TrailheadAshish Yaduka Trailhead
Thanks Dobias! You saved a big day for us! Seeall data = true didn't work but your solution worked. I owe you a beer, maybe two! 
Colton KloppelColton Kloppel

Thanks Dobias!  I had to hunt down my developer credentials just to give you a thumbs up on this.   

I've always been told that the SeeAllData = True solution is NOT best practice. 

The FSL.GlobalAPIS.addStatusTransition('New', 'Scheduled'); seems to be a better solution, so thank you.

Andrew GAndrew G
Trawling my old posts.  Thanks Dobias for the extra info.  As noted, we all know that SeeAllData is not best practice, so a solution that avoids this is appreciated.

regards
Andrew
Ashams JaisonAshams Jaison
Awesome information Dobias! Add the below line in your test setup method and the error is resolved.
Tushar Thakare 7Tushar Thakare 7
I am facing the same issue, but in the flow. I am using the service appointment object and trying to update the status.

But its giving error 'Error Occurred: The flow tried to update these records: 08p5j000000Tc9zAAC. This error occurred: FIELD_CUSTOM_VALIDATION_EXCEPTION: Cannot change status from None to Completed. You can look up ExceptionCode values in the SOAP API Developer Guide.'

Please suggest. How we can avoid the issue in the flow ?
Dobias van Buuren 5Dobias van Buuren 5
Hi Tushar, you have enforced Service Appointment Status Transitions in the Service Appointment Life Cycle section in Field Service Settings. But you are missing the allowed status transition from None to Completed. That is why you get this error from the Field Service Managed package triggers.
I think you should either do one of the following:
  1. Change the application logic in your flow to make it impossible to do status transitions that are not allowed (none to completed seems a little strange to me, but maybe there is a valid use case for this.
  2. Add the status transition from None to Completed in the Service Appointment Life Cycle Status transitions
  3. Turn of Service Appointment Status Transition validation in from within the Status Transitions tab in the Service Appointment Life Cycle settings (although I would not recommend this, but this will solve your issue).
Good luck.

Regards,

Dobias van Buuren
Duncan Brown 3Duncan Brown 3
https://help.salesforce.com/s/articleView?id=sf.pfs_lifecycle.htm&type=5

I had a similar issue recently, and found this article userful to solve the issue. As per @dobias above you need to tinker with the "Service Appointment Life Cycle" in the Field Service Settings to allow the transition between service appointment statuses