def compute_automatic_staffing(mission, mode, duration, user=None): """Compute staffing for a given mission. Mode can be after (current staffing) for replace (erase and create)""" now = datetime.now().replace(microsecond=0) # Remove useless microsecond current_month = date.today().replace(day=1) start_date = current_month total = 0 if not mission.consultants(): # no consultant, no staffing. Come on. return if mode=="replace": mission.staffing_set.all().delete() cache.delete("Mission.forecasted_work%s" % mission.id) cache.delete("Mission.done_work%s" % mission.id) if mission.lead: start_date = max(current_month, mission.lead.start_date.replace(day=1)) else: max_staffing = Staffing.objects.filter(mission=mission).aggregate(Max("staffing_date"))["staffing_date__max"] if max_staffing: start_date = max(current_month, nextMonth(max_staffing)) if mission.start_date: start_date = max(start_date, mission.start_date) margin = mission.remaining(mode="target") rates = mission.consultant_rates() rates_sum = sum([i[0] for i in rates.values()]) days = margin*1000 / rates_sum / duration days = max(floor(days * 4) / 4, 0.25) for consultant in rates.keys(): month = start_date for i in range(duration): if total > margin*1000: break if mission.end_date and month > mission.end_date: break s = Staffing(mission=mission, consultant=consultant, charge=days, staffing_date=month, update_date = now) if user: s.last_user = str(user) s.save() total += days * rates[consultant][0] month = nextMonth(month)
def solver_apply_forecast(solver, staffing, consultants, missions, staffing_dates, user): """Apply solver solution to staffing forecast""" now = datetime.now().replace(microsecond=0) # Remove useless microsecond for mission in missions: mission_id = mission.mission_id() # Remove previous staffing for this mission after first month Staffing.objects.filter( mission=mission, staffing_date__gte=staffing_dates[0][0]).delete() # Create new staffing according to solver solution for consultant in consultants: for month in staffing_dates: charge = solver.Value( staffing[consultant.trigramme][mission_id][month[1]]) if charge > 0: s = Staffing(mission=mission, consultant=consultant, staffing_date=month[0], charge=charge, update_date=now, last_user=str(user)) s.save()
def compute_automatic_staffing(mission, mode, duration, user=None): """Compute staffing for a given mission. Mode can be after (current staffing) for replace (erase and create)""" now = datetime.now().replace(microsecond=0) # Remove useless microsecond current_month = date.today().replace(day=1) start_date = current_month total = 0 if mode=="replace": mission.staffing_set.all().delete() cache.delete("Mission.forecasted_work%s" % mission.id) cache.delete("Mission.done_work%s" % mission.id) if mission.lead: start_date = max(current_month, mission.lead.start_date.replace(day=1)) else: max_staffing = Staffing.objects.filter(mission=mission).aggregate(Max("staffing_date"))["staffing_date__max"] if max_staffing: start_date = max(current_month, nextMonth(max_staffing)) margin = mission.margin(mode="target") rates = mission.consultant_rates() rates_sum = sum([i[0] for i in rates.values()]) days = margin*1000 / rates_sum / duration days = max(floor(days * 4) / 4, 0.25) for consultant in rates.keys(): month = start_date for i in range(duration): if total > margin*1000: break s = Staffing(mission=mission, consultant=consultant, charge=days, staffing_date=month, update_date = now) if user: s.last_user = str(user) s.save() total += days * rates[consultant][0] month = nextMonth(month)