def calculate_allocation(allocation, print_logs=False): (window_start_date, window_end_date) = get_allocation_window(allocation) # FYI: Calculates time periods based on allocation.credits current_result = AllocationResult( allocation, window_start_date, window_end_date, force_interval_every=allocation.interval_delta) if print_logs: logger.debug( "New AllocationResult, Start On & (End On): %s (%s)" % (current_result.window_start, current_result.window_end)) instance_rules = [] # First loop - Apply all global rules. # Collect instance rules seperately. for rule in allocation.rules: if issubclass(rule.__class__, GlobalRule): rule.apply_global_rule(allocation, current_result) elif issubclass(rule.__class__, InstanceRule): # Non-global rules assumed to be applied at instance-level. # Keeping them seperate for now.. instance_rules.append(rule) else: raise Exception("Unknown Type of Rule: %s" % rule) time_forward = timedelta(0) for current_period in current_result.time_periods: if current_result.carry_forward and time_forward: current_period.increase_credit(time_forward, carry_forward=True) if print_logs: logger.debug("> New TimePeriodResult: %s" % current_period) if current_period.total_credit > timedelta(0): logger.debug("> > Allocation Increased: %s" % current_period.total_credit) # Second loop - Go through all the instances and apply # the specific rules (This loop relates to time USED) instance_results = [] for instance in allocation.instances: # "Chatty" Warning - Uncomment at your own risk # logger.debug("> > Calculating Instance history:%s" # % instance.identifier) history_list = _calculate_instance_history_list( instance, instance_rules, current_period.start_counting_date, current_period.stop_counting_date, print_logs=print_logs) if not history_list: continue instance_result = InstanceResult( identifier=instance.identifier, history_list=history_list) instance_results.append(instance_result) if print_logs: logger.debug("> > Instance history Results:") for instance_result in instance_results: logger.debug("> > %s" % instance_result) current_period.instance_results = instance_results if print_logs: logger.debug("> > %s - %s = %s" % (current_period.total_credit, current_period.total_instance_runtime(), current_period.allocation_difference())) if current_result.carry_forward: time_forward = current_period.allocation_difference() return current_result
def _empty_allocation_result(): """ """ return AllocationResult.no_allocation()