def get_resource_available_in_dt_range(candidate_resources, dt_range, new_resource_occupations): """ Try to find a resource available in dt_range, if no resource finded return None. """ for resource in candidate_resources: # Only occupations of current resource res_new_occupations = [y[1] for y in filter( lambda x: x[0] == clean_resource(resource), new_resource_occupations)] # Check availability availability = resource.get('availability') if (availability and not is_datetime_range_available(dt_range, availability)): continue # Check occupations occupations = resource.get('occupations', []) + res_new_occupations overlappings = [overlaps(dt_range, o) for o in occupations] if any(overlappings): continue return resource return None
def calculate_ranges(period, availability, service_recipe, resources): """ Calculates available time ranges and resulting resources configuration, given: * period: tuple of two datetimes * availability: dict describing global shop availability * service_recipe: list of needed resources and relative timings * resources: availability (from configuration) and occupation (from allocated services) of each resource """ ranges = [] period_start_dt, period_end_dt = period delta_duration = get_service_duration(service_recipe) delta_step = get_service_step(service_recipe) loop_dt_range = by_timedelta_range((timedelta(0), delta_duration), period_start_dt) while contains(period, loop_dt_range): if not is_datetime_range_available(loop_dt_range, availability): near_working_dt_range = nearest_working_datetime_range( loop_dt_range, availability) if near_working_dt_range is not None: loop_dt_range = by_timedelta_range( (timedelta(0), delta_duration), near_working_dt_range[0]) else: loop_dt_range = by_timedelta_range( (timedelta(0), delta_duration), start_of_tomorrow(loop_dt_range[0])) continue resource_occupations = get_resource_occupations_in_dt_range( loop_dt_range, service_recipe, resources) if resource_occupations: ranges.append((loop_dt_range, resource_occupations)) # like i++ but more cool loop_dt_range = by_timedelta_range( (delta_step, delta_step + delta_duration), loop_dt_range[0]) return ranges