예제 #1
0
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
예제 #2
0
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