def create_next_year_std_missions(current, target, dryrun=True, start_date=None, end_date=None): """Create default set of mission for next year based on current holidays and nonprod missions @current: current suffix @target: target suffix @dryrun: save new mission or just print its @start_date: mission start boundary @end_date: mission end boundary""" for m in Mission.objects.exclude(nature="PROD").filter(active=True): if not m.description or current not in m.description: continue new_mission = Mission(description=m.description.replace( current, target), subsidiary=m.subsidiary, nature=m.nature, billing_mode="TIME_SPENT", probability=100, probability_auto=False, analytic_code=m.analytic_code, start_date=start_date, end_date=end_date) print("Creating new mission %s" % new_mission) if not dryrun: new_mission.save()
def create_default_mission(lead): mission = Mission(lead=lead) mission.price = lead.sales # Initialise with lead price mission.subsidiary = lead.subsidiary mission.responsible = lead.responsible try: mission.probability = lead.stateproba_set.get(state="WON").score except StateProba.DoesNotExist: # No state proba, leave mission proba default pass mission.save() # Create default staffing mission.create_default_staffing() return mission
def create_next_year_std_missions(current, target, dryrun=True): """Create default set of mission for next year based on current holidays and nonprod missions @current: current suffix @target: target suffix @dryrun: save new mission or just print its""" for m in Mission.objects.exclude(nature="PROD").filter(active=True): if not current in m.description: continue new_mission = Mission(description = m.description.replace(current, target), subsidiary = m.subsidiary, nature = m.nature, billing_mode = "TIME_SPENT", probability = 100, probability_auto = False) print("Creating new mission %s" % new_mission) if not dryrun: new_mission.save()
def test_turnover(self): current_month = date.today().replace(day=1) next_month = nextMonth(current_month) previous_month = previousMonth(current_month) lead = Lead.objects.get(id=1) c1 = Consultant.objects.get(id=1) c2 = Consultant.objects.get(id=2) mission = Mission(lead=lead, subsidiary_id=1, billing_mode="TIME_SPENT", nature="PROD", probability=100) mission.save() cache.clear() # avoid bad computation due to rates cache with previous values # Add some timesheet - we fake with all charge on the first day Timesheet(mission=mission, working_date=previous_month, consultant=c1, charge=10).save() Timesheet(mission=mission, working_date=previous_month, consultant=c2, charge=5).save() Timesheet(mission=mission, working_date=current_month, consultant=c1, charge=10).save() Timesheet(mission=mission, working_date=current_month, consultant=c2, charge=5).save() # Add financial conditions for this mission FinancialCondition(consultant=c1, mission=mission, daily_rate=2000).save() FinancialCondition(consultant=c2, mission=mission, daily_rate=1000).save() done_work = (10 + 10) * 2000 + (5 + 5) * 1000 # Define mission price mission.price = 40 mission.billing_mode = "TIME_SPENT" mission.save() # In time spent, turnover is what we did self.assertEqual(c1.get_turnover(end_date=next_month), 20 * 2000) mission.billing_mode = "FIXED_PRICE" mission.save() # In fixed price, turnover is limited by price in proportion of all work self.assertEqual(c1.get_turnover(end_date=next_month), 20 * 2000 * mission.price * 1000 / done_work) self.assertEqual(c1.get_turnover(end_date=next_month) + c2.get_turnover(end_date=next_month), mission.price * 1000) # Let add some margin by changing mission price. mission.price = 60 mission.save() self.assertEqual(c1.get_turnover(end_date=next_month), 20 * 2000) # like in time spent self.assertEqual(c1.get_turnover(end_date=next_month) + c2.get_turnover(end_date=next_month), done_work) # Let archive mission to validate margin mission.active = False mission.save() self.assertEqual(c1.get_turnover(end_date=next_month), 20 * 2000 * mission.price * 1000 / done_work) # like in time spent self.assertEqual(c1.get_turnover(end_date=next_month) + c2.get_turnover(end_date=next_month), mission.price * 1000)
def test_mission_timesheet(self): self.client.login(username=TEST_USERNAME, password=TEST_PASSWORD) current_month = date.today().replace(day=1) next_month = nextMonth(current_month) previous_month = previousMonth(current_month) lead = Lead.objects.get(id=1) c1 = Consultant.objects.get(id=1) c2 = Consultant.objects.get(id=2) mission = Mission(lead=lead, subsidiary_id=1, billing_mode="TIME_SPENT", nature="PROD", probability=100) mission.save() response = self.client.get(urlresolvers.reverse("staffing.views.mission_timesheet", args=[mission.id,]), follow=True, HTTP_X_REQUESTED_WITH="XMLHttpRequest") self.assertEqual(response.status_code, 200) self.assertEqual(response.context["margin"], 0) self.assertEqual(response.context["objective_margin_total"], 0) self.assertEqual(response.context["forecasted_unused"], 0) self.assertEqual(response.context["current_unused"], 0) self.assertEqual(response.context["avg_daily_rate"], 0) # Add some forecast Staffing(mission=mission, staffing_date=current_month, consultant=c1, charge=15).save() Staffing(mission=mission, staffing_date=current_month, consultant=c2, charge=10).save() Staffing(mission=mission, staffing_date=next_month, consultant=c1, charge=8).save() Staffing(mission=mission, staffing_date=next_month, consultant=c2, charge=6).save() # Add some timesheet - we fake with all charge on the first day Timesheet(mission=mission, working_date=previous_month, consultant=c1, charge=8).save() Timesheet(mission=mission, working_date=previous_month, consultant=c2, charge=5).save() Timesheet(mission=mission, working_date=current_month, consultant=c1, charge=11).save() Timesheet(mission=mission, working_date=current_month, consultant=c2, charge=9).save() # Define objective rates for consultants RateObjective(consultant=c1, start_date=previous_month, daily_rate=700).save() RateObjective(consultant=c2, start_date=previous_month, daily_rate=1050).save() # Add financial conditions for this mission FinancialCondition(consultant=c1, mission=mission, daily_rate=800).save() FinancialCondition(consultant=c2, mission=mission, daily_rate=1100).save() # Define mission price mission.price = 50 mission.save() # Let's test if computation are rights response = self.client.get(urlresolvers.reverse("staffing.views.mission_timesheet", args=[mission.id,]), follow=True, HTTP_X_REQUESTED_WITH="XMLHttpRequest") self.assertEqual(response.status_code, 200) self.assertEqual(response.context["margin"], 0) # That's because we are in fixed price self.assertEqual(response.context["objective_margin_total"], 2600) self.assertEqual(response.context["forecasted_unused"], 2.1) self.assertEqual(response.context["current_unused"], 19.4) # Switch to fixed price mission mission.billing_mode = "FIXED_PRICE" mission.save() response = self.client.get(urlresolvers.reverse("staffing.views.mission_timesheet", args=[mission.id,]), follow=True, HTTP_X_REQUESTED_WITH="XMLHttpRequest") self.assertEqual(response.status_code, 200) self.assertEqual(response.context["margin"], 2.1) self.assertEqual(response.context["objective_margin_total"], 2600) self.assertEqual(response.context["forecasted_unused"], 0) # Unused is margin in fixes price :-) self.assertEqual(response.context["current_unused"], 0) # idem # Check mission data main table data = response.context["mission_data"] self.assertListEqual(data[0], [c2, [5, 9, 14, 15.4], [1, 6, 7, 7.7], [21, 23.1]]) self.assertListEqual(data[1], [c1, [8, 11, 19, 15.2], [4, 8, 12, 9.6], [31, 24.8]]) self.assertListEqual(data[2], [None, [13, 20, 33, 30.6], [5, 14, 19, 17.3], [52, 47.9], [11.9, 18.7], [4.3, 13], [915.4, 935, 927.3], [860, 928.6, 910.5]])
def test_mission_timesheet(self): self.client.force_login(self.test_user) current_month = date.today().replace(day=1) next_month = nextMonth(current_month) previous_month = previousMonth(current_month) lead = Lead.objects.get(id=1) c1 = Consultant.objects.get(id=1) c2 = Consultant.objects.get(id=2) mission = Mission(lead=lead, subsidiary_id=1, billing_mode="TIME_SPENT", nature="PROD", probability=100) mission.save() cache.clear() # avoid bad computation due to rates cache with previous values response = self.client.get(urlresolvers.reverse("staffing:mission_timesheet", args=[mission.id,]), follow=True, HTTP_X_REQUESTED_WITH="XMLHttpRequest") self.assertEqual(response.status_code, 200) self.assertEqual(response.context["margin"], 0) self.assertEqual(response.context["objective_margin_total"], 0) self.assertEqual(response.context["forecasted_unused"], 0) self.assertEqual(response.context["current_unused"], 0) self.assertEqual(response.context["avg_daily_rate"], 0) # Add some forecast Staffing(mission=mission, staffing_date=current_month, consultant=c1, charge=15).save() Staffing(mission=mission, staffing_date=current_month, consultant=c2, charge=10).save() Staffing(mission=mission, staffing_date=next_month, consultant=c1, charge=8).save() Staffing(mission=mission, staffing_date=next_month, consultant=c2, charge=6).save() # Add some timesheet - we fake with all charge on the first day Timesheet(mission=mission, working_date=previous_month, consultant=c1, charge=8).save() Timesheet(mission=mission, working_date=previous_month, consultant=c2, charge=5).save() Timesheet(mission=mission, working_date=current_month, consultant=c1, charge=11).save() Timesheet(mission=mission, working_date=current_month, consultant=c2, charge=9).save() # Define objective rates for consultants RateObjective(consultant=c1, start_date=previous_month, rate=700, rate_type="DAILY_RATE").save() RateObjective(consultant=c2, start_date=previous_month, rate=1050, rate_type="DAILY_RATE").save() # Add financial conditions for this mission FinancialCondition(consultant=c1, mission=mission, daily_rate=800).save() FinancialCondition(consultant=c2, mission=mission, daily_rate=1100).save() # Define mission price mission.price = 50 mission.save() # Let's test if computation are rights cache.clear() # avoid bad computation due to rates cache with previous values response = self.client.get(urlresolvers.reverse("staffing:mission_timesheet", args=[mission.id,]), follow=True, HTTP_X_REQUESTED_WITH="XMLHttpRequest") self.assertEqual(response.status_code, 200) self.assertEqual(response.context["margin"], 0) # That's because we are in fixed price self.assertEqual(response.context["objective_margin_total"], 2600) self.assertEqual(response.context["forecasted_unused"], 2.1) self.assertEqual(response.context["current_unused"], 19.4) # Switch to fixed price mission mission.billing_mode = "FIXED_PRICE" mission.save() response = self.client.get(urlresolvers.reverse("staffing:mission_timesheet", args=[mission.id,]), follow=True, HTTP_X_REQUESTED_WITH="XMLHttpRequest") self.assertEqual(response.status_code, 200) self.assertEqual(response.context["margin"], 2.1) self.assertEqual(response.context["objective_margin_total"], 2600) self.assertEqual(response.context["forecasted_unused"], 0) # Unused is margin in fixes price :-) self.assertEqual(response.context["current_unused"], 0) # idem # Check mission data main table data = list(response.context["mission_data"]) self.assertListEqual(data[0], [c2, [5, 9, 14, 15.4], [1, 6, 7, 7.7], [21, 23.1], None, None, None, None]) self.assertListEqual(data[1], [c1, [8, 11, 19, 15.2], [4, 8, 12, 9.6], [31, 24.8], None, None, None, None]) self.assertListEqual(data[2], [None, [13, 20, 33, 30.6], [5, 14, 19, 17.3], [52, 47.9], [11.9, 18.7], [4.3, 13], [915.4, 935, 927.3], [860, 928.6, 910.5]])
(request.user.first_name, request.user.last_name)) messages.add_message( request, messages.INFO, ugettext("Lead sent to business mailing list")) except Exception, e: messages.add_message(request, messages.ERROR, ugettext("Failed to send mail: %s") % e) # Create or update mission if needed if lead.mission_set.count() == 0: if lead.state in ("OFFER_SENT", "NEGOTIATION", "WON"): mission = Mission(lead=lead) mission.price = lead.sales # Initialise with lead price mission.subsidiary = lead.subsidiary mission.responsible = lead.responsible mission.save() # Create default staffing mission.create_default_staffing() messages.add_message( request, messages.INFO, ugettext("A mission has been initialized for this lead.")) for mission in lead.mission_set.all(): if mission.subsidiary != lead.subsidiary: mission.subsidiary = lead.subsidiary mission.save() if lead.state == "WON": mission.probability = 100 mission.active = True mission.save() messages.add_message(
try: fromAddr = request.user.email or "*****@*****.**" send_lead_mail(lead, request, fromAddr=fromAddr, fromName="%s %s" % (request.user.first_name, request.user.last_name)) messages.add_message(request, messages.INFO, ugettext("Lead sent to business mailing list")) except Exception, e: messages.add_message(request, messages.ERROR, ugettext("Failed to send mail: %s") % e) # Create or update mission if needed if lead.mission_set.count() == 0: if lead.state in ("OFFER_SENT", "NEGOTIATION", "WON"): mission = Mission(lead=lead) mission.price = lead.sales # Initialise with lead price mission.subsidiary = lead.subsidiary mission.responsible = lead.responsible mission.save() # Create default staffing mission.create_default_staffing() messages.add_message(request, messages.INFO, ugettext("A mission has been initialized for this lead.")) for mission in lead.mission_set.all(): if mission.subsidiary != lead.subsidiary: mission.subsidiary = lead.subsidiary mission.save() if lead.state == "WON": mission.probability = 100 mission.active = True mission.save() messages.add_message(request, messages.INFO, ugettext("Mission's probability has been set to 100%")) elif lead.state in ("LOST", "FORGIVEN", "SLEEPING"): mission.probability = 0