Real-Life Service Board Validation Code Examples
The following annotated code examples can be used as a reference for development.
package com.servicemax.dc.validator


import com.intalio.core.translation.TranslationFactory
import com.servicemax.core.Database
import com.servicemax.core.annotations.Application
import com.servicemax.core.validator.OperationValidator

@Application(application = 'svmx_dispatch_console')
class CrewValidator extends OperationValidator { //Extending OperationValidator makes it easier to write validators

//This is the method automatically called to execute the validation
@Override
public Object realValidator(Map<String, Object> parameters) {
validateDeactivate()
}

/**
* No appointment start after current
*/
private void validateDeactivate() {
def crewId = recordUnderValidation.recordID.toString() //recordUnderValidation variable is automatically loaded with the record to validate
//in this case the crew

if (recordUnderValidation.getOldFieldValue('io_active') && !recordUnderValidation.io_active) {
Integer appointmentSize = Database.queryObject('SELECT COUNT() FROM svmx_appointment WHERE svmx_crew = :io_uuid and svmx_start_datetime > :current_datetime AND svmx_workflow_final IS NOT TRUE', [
io_uuid: crewId, current_datetime: new Date()
])

if (appointmentSize > 0) {
//This indicates that one validation has failed. More than one failure can be indicated for a given record
//The error message for the validation is internationalized.
this.addFieldValidationError('io_active',
TranslationFactory.getByFullIdentifier('svmx_please_reassign_jobs_to_other_crews_before_deactivating_this_crew'))
}
}
}
}
package com.servicemax.dc.validator

import com.intalio.core.translation.TranslationFactory
import com.servicemax.core.annotations.Application
import com.servicemax.core.validator.OperationValidator
import com.servicemax.dc.service.JobService

/**
* Validator operation for svmx_job records.
*/
@Application(application = 'svmx_dispatch_console')
class JobValidator extends OperationValidator {
private static final String MA_FIELD = 'svmx_multiple_assignments'
private final JobService jobServiceInstance = JobService.getInstance()

@Override
public Object realValidator(Map<String, Object> params) {
validateMAField()
}

/**
* Check whether the multiple assignments change is allowed.
*/
private void validateMAField() {
// skip if multiple assignments is not changed or new record
if (!recordUnderValidation.isFieldChanged(MA_FIELD) || recordUnderValidation.isNewRecord()) {
return
}

String jobUUID = recordUnderValidation.getRecordID().toString()
def job = jobServiceInstance.getJobAppointments(jobUUID)

if (job.isStatusEnd) {
this.addFieldValidationError(MA_FIELD,
TranslationFactory.getByFullIdentifier('svmx_dc_currently_a_job_cant_be_editable_if_it_is_already_ended'))
} else {
def multipleAssignmentsValue = recordUnderValidation.getFieldValue(MA_FIELD)
if (multipleAssignmentsValue) {
// has open crew appointment
def hasOpenCrewAppt = job.events.any { return it.crewId && !it.isStatusEnd }
if (hasOpenCrewAppt) {
this.addFieldValidationError(MA_FIELD,
TranslationFactory.getByFullIdentifier('svmx_the_job_was_dispatched_to_a_crew_and_cannot_be_configured_for_ma'))
}
} else {
// has more than one open appointment (not crew)
def hasOpenAppt = job.events.findAll { return !it.crewId && !it.isStatusEnd }
if (hasOpenAppt.size > 1) {
this.addFieldValidationError(MA_FIELD,
TranslationFactory.getByFullIdentifier('svmx_dc_the_multiple_assignments_field_cannot_be_unset_when_there_are_multiple_open_appointments_related_to_the_job'))
}
}
}
}
}
* 
For details on how to configure custom data validation, see Working With Data Validation Options in Service Board for Implementers.
For more information:
Was this helpful?