Hi,
I'm currently working with DOM and try to validate some fields. One of them is a resource select field. I would like to check if the resource is available (as in not currently in use.) what is the best way to get the current state of an resource?
Hi Gerwin,
The answer of Hideyuki is correct, but I would like to give some additions that might be useful.
The GetEligibleResources method will return all resources that meet the requirements as defined in the context. If you already have the id of the resource, you can limit the scope of GetEligibleResources to one resource with a filter, which will reduce the processing the server needs to do. Without a filter the availability of all resources is calculated. Furthermore, the example of Hideyuki will calculate the availability of the resource now, not for a later timerange. I assume the intention is to create a booking that uses the resource, in which case you need to pass the timerange of the booking to GetEligibleResources. An example with a filter:
private bool IsResourceInUse(Guid resourceId, DateTime start, DateTime end)
{
var context = new EligibleResourceContext(start, end)
{
ResourceFilter = ResourceExposers.ID.Equal(resourceId)
};// You can add capacities or capabilities to the context if you want to make sure
// the resource has certain capacities and capabilities available in the time range as well.
// context.RequiredCapabilities.Add(new ResourceCapabilityUsage()
// {
// CapabilityProfileID = Guid.NewGuid(), // ID of the capability parameter
// RequiredDiscreet = "Example" // Discreet capability value that is required
// });
// context.RequiredCapacities.Add(new MultiResourceCapacityUsage()
// {
// CapacityProfileID = Guid.NewGuid(), // ID of the capacity parameter
// DecimalQuantity = 100 // Amount of capacity required
// });var result = rmHelper.GetEligibleResources(context);
// Result should only contain one resource since we filter on ID.
var resourceInResult = result.EligibleResources.FirstOrDefault(resource => resource.ID == resourceId);
return resourceInResult != null;
}
Some other remarks that might be important:
- If the resource is already in use by another booking, but there is still concurrency left, and the filtered capacities and capabilities are still available, the resource will still be returned in the result, since another booking can make use of it in that timerange. If you also want to make sure there is not a single booking in the passed timerange using the resource, you can check if the 'ConcurrencyLeft' for the resource is different from the max concurrency on the resource. The concurrency left per resource can be found in the 'UsageDetails' list of the result:
var result = rmHelper.GetEligibleResources(context);
var usageDetails = result.UsageDetails.FirstOrDefault(resource => resource.ID == resourceId);
return usageDetails.ConcurrencyLeft == resource.GetEffectiveMaxConcurrency();
- If you have multiple resources to validate, don't filter on one ID but filter on multiple IDs in the filter of the context. Requesting the availability of multiple resources in one call is more efficient than making multiple calls.
- If you call GetEligibleResources but don't create a booking with the resource, there is nothing stopping a different script from 'stealing' the resource and creating a booking with it. GetEligibleResources only calculates availability of resources, it does not book resources. It might be interesting if you share how or where you validate these DOM fields, as there is (as far as I know) no built-in mechanism to validate fields based on custom logic.
Hi,
Thanks for the extra explanations. It’s an basic validation to catch any user errors in an early stage, after this validation step an booking can be triggered. But it is to catch user config/copy paste errors (duplicate names, resources, other config items)