예제 #1
0
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()
예제 #2
0
파일: tests.py 프로젝트: agateau/pydici
 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]])
예제 #3
0
파일: utils.py 프로젝트: xyzlat/pydici
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
예제 #4
0
파일: utils.py 프로젝트: fbeziaud/pydici
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()
예제 #5
0
파일: utils.py 프로젝트: digitalfox/pydici
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
예제 #6
0
파일: tests.py 프로젝트: fbeziaud/pydici
 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]])
예제 #7
0
 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)
예제 #8
0
            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":
예제 #9
0
파일: utils.py 프로젝트: apocweb/pydici
        change_message  = ", ".join(updated_fields),
    )

    if mail:
        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