RE: Universal resource scheduling: Stop duplicate bookings
Hi,
Please register the below two plug-in steps which checks if there is already a booking exist for the selected resource which falls within the provided start and end time.
1. Pre Create of Bookable Resource Booking
2. Post Update of Bookable Resource Booking (filter attributes: starttime, endtime and resource. Pre Image: PreImage)
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity entity = (Entity)context.InputParameters["Target"];
Entity preImage = (Entity)context.PreEntityImages["PreImage"];
EntityReference resource = entity.Contains("resource") ? entity.GetAttributeValue("resource") :
(preImage.Contains("resource") ? preImage.GetAttributeValue("resource") : null);
DateTime startTime = entity.Contains("starttime") ? entity.GetAttributeValue("starttime") :
(preImage.Contains("starttime") ? preImage.GetAttributeValue("starttime").ToLocalTime() : DateTime.MinValue);
DateTime endTime = entity.Contains("endtime") ? entity.GetAttributeValue("endtime") :
(preImage.Contains("endtime") ? preImage.GetAttributeValue("endtime").ToLocalTime() : DateTime.MinValue);
if (startTime != DateTime.MinValue && endTime != DateTime.MinValue)
{
if (IsDuplicateBoking(service, entity.Id, resource, startTime, endTime))
throw new InvalidPluginExecutionException("Duplicate Booking");
}
}
}
public bool IsDuplicateBoking(IOrganizationService service, Guid newBookingId, EntityReference resource, DateTime startTime, DateTime endTime)
{
bool isDuplicate = false;
QueryExpression query = new QueryExpression("bookableresourcebooking")
{
ColumnSet = new ColumnSet("starttime", "endtime"),
Criteria = { Conditions = { new ConditionExpression("resource", ConditionOperator.Equal, resource.Id),
new ConditionExpression("bookableresourcebookingid", ConditionOperator.NotEqual, newBookingId),
new ConditionExpression("statecode", ConditionOperator.Equal, 0)} }
};
EntityCollection existingBookings = service.RetrieveMultiple(query);
foreach (Entity booking in existingBookings.Entities)
{
DateTime existingStartTime = booking.Contains("starttime") ? booking.GetAttributeValue("starttime") : DateTime.MinValue,
existingEndTime = booking.Contains("endtime") ? booking.GetAttributeValue("endtime") : DateTime.MinValue;
if (existingStartTime != DateTime.MinValue && existingEndTime != DateTime.MinValue)
{
isDuplicate = (existingStartTime >= startTime && existingStartTime < endTime) || (existingEndTime > startTime && existingEndTime <= endTime);
if (isDuplicate)
break;
}
}
return isDuplicate;
}
Below is the validation error message appears when user try to book a same resource with overlapping time slot.