Esempio n. 1
0
def timesheet_report_data(mission, start=None, end=None, padding=False):
    """Prepare data for timesheet report from start to end.
    Padding align total in the same column"""
    timesheets = Timesheet.objects.select_related().filter(mission=mission)
    months = timesheets.dates("working_date", "month")
    data = []

    for month in months:
        if start and month < start:
            continue
        if end and month > end:
            break
        days = daysOfMonth(month)
        next_month = nextMonth(month)
        padding_length = 31 - len(
            days
        )  # Padding for month with less than 31 days to align total column
        # Header
        data.append([""])
        data.append([formats.date_format(month, format="YEAR_MONTH_FORMAT")])

        # Days
        data.append([
            "",
        ] + [d.day for d in days])
        dayHeader = [_("Consultants")] + [_(d.strftime("%a")) for d in days]
        if padding:
            dayHeader.extend([""] * padding_length)
        dayHeader.append(_("total"))
        data.append(dayHeader)

        for consultant in mission.consultants():
            total = 0
            row = [
                consultant,
            ]
            consultant_timesheets = {}
            for timesheet in timesheets.filter(consultant_id=consultant.id,
                                               working_date__gte=month,
                                               working_date__lt=next_month):
                consultant_timesheets[
                    timesheet.working_date] = timesheet.charge
            for day in days:
                try:
                    charge = consultant_timesheets.get(day)
                    if charge:
                        row.append(
                            formats.number_format(to_int_or_round(charge, 2)))
                        total += charge
                    else:
                        row.append("")
                except Timesheet.DoesNotExist:
                    row.append("")
            if padding:
                row.extend([""] * padding_length)
            row.append(formats.number_format(to_int_or_round(total, 2)))
            if total > 0:
                data.append(row)

    return data
Esempio n. 2
0
def gatherTimesheetData(consultant, missions, month):
    """Gather existing timesheet timesheetData
    @returns: (timesheetData, timesheetTotal, warning)
    timesheetData represent timesheet form post timesheetData as a dict
    timesheetTotal is a dict of total charge (key is mission id)
    warning is a list of 0 (ok) or 1 (surbooking) or 2 (no data). One entry per day"""
    timesheetData = {}
    timesheetTotal = {}
    warning = []
    totalPerDay = [0] * month_days(month)
    next_month = nextMonth(month)
    for mission in missions:
        timesheets = Timesheet.objects.select_related().filter(
            consultant=consultant).filter(mission=mission)
        timesheets = timesheets.filter(working_date__gte=month).filter(
            working_date__lt=next_month)
        for timesheet in timesheets:
            timesheetData["charge_%s_%s" %
                          (timesheet.mission.id,
                           timesheet.working_date.day)] = timesheet.charge
            if mission.id in timesheetTotal:
                timesheetTotal[mission.id] += timesheet.charge
            else:
                timesheetTotal[mission.id] = timesheet.charge
            totalPerDay[timesheet.working_date.day - 1] += timesheet.charge
    # Gather lunck ticket data
    totalTicket = 0
    lunchTickets = LunchTicket.objects.filter(consultant=consultant)
    lunchTickets = lunchTickets.filter(lunch_date__gte=month).filter(
        lunch_date__lt=next_month)
    for lunchTicket in lunchTickets:
        timesheetData["lunch_ticket_%s" %
                      lunchTicket.lunch_date.day] = lunchTicket.no_ticket
        totalTicket += 1
    timesheetTotal["ticket"] = totalTicket
    # Compute warnings (overbooking and no data)
    for i in totalPerDay:
        i = round(
            i, 4
        )  # We must round because using keyboard time input may lead to real numbers that are truncated
        if i > 1:  # Surbooking
            warning.append(1)
        elif i == 1:  # Ok
            warning.append(0)
        else:  # warning (no data, or half day)
            warning.append(2)
    # Don't emit warning for no data during week ends and holidays
    holiday_days = holidayDays(month)
    for day in daysOfMonth(month):
        if day.isoweekday() in (6, 7) or day in holiday_days:
            warning[day.day - 1] = None

    return (timesheetData, timesheetTotal, warning)
Esempio n. 3
0
def timesheet_report_data(mission, start=None, end=None, padding=False):
    """Prepare data for timesheet report from start to end.
    Padding align total in the same column"""
    timesheets = Timesheet.objects.select_related().filter(mission=mission)
    months = timesheets.dates("working_date", "month")
    data = []

    for month in months:
        if start and month < start:
            continue
        if end and month > end:
            break
        days = daysOfMonth(month)
        next_month = nextMonth(month)
        padding_length = 31 - len(days)  # Padding for month with less than 31 days to align total column
        # Header
        data.append([""])
        data.append([formats.date_format(month, format="YEAR_MONTH_FORMAT")])

        # Days
        data.append(["", ] + [d.day for d in days])
        dayHeader = [_("Consultants")] + [_(d.strftime("%a")) for d in days]
        if padding:
            dayHeader.extend([""] * padding_length)
        dayHeader.append(_("total"))
        data.append(dayHeader)

        for consultant in mission.consultants():
            total = 0
            row = [consultant, ]
            consultant_timesheets = {}
            for timesheet in timesheets.filter(consultant_id=consultant.id,
                                               working_date__gte=month,
                                               working_date__lt=next_month):
                consultant_timesheets[timesheet.working_date] = timesheet.charge
            for day in days:
                try:
                    charge = consultant_timesheets.get(day)
                    if charge:
                        row.append(formats.number_format(to_int_or_round(charge, 2)))
                        total += charge
                    else:
                        row.append("")
                except Timesheet.DoesNotExist:
                    row.append("")
            if padding:
                row.extend([""] * padding_length)
            row.append(formats.number_format(to_int_or_round(total, 2)))
            if total > 0:
                data.append(row)

    return data
Esempio n. 4
0
def gatherTimesheetData(consultant, missions, month):
    """Gather existing timesheet timesheetData
    @returns: (timesheetData, timesheetTotal, warning)
    timesheetData represent timesheet form post timesheetData as a dict
    timesheetTotal is a dict of total charge (key is mission id)
    warning is a list of 0 (ok) or 1 (surbooking) or 2 (no data). One entry per day"""
    timesheetData = {}
    timesheetTotal = {}
    warning = []
    totalPerDay = [0] * month_days(month)
    next_month = nextMonth(month)
    for mission in missions:
        timesheets = Timesheet.objects.select_related().filter(consultant=consultant).filter(mission=mission)
        timesheets = timesheets.filter(working_date__gte=month).filter(working_date__lt=next_month)
        for timesheet in timesheets:
            timesheetData["charge_%s_%s" % (timesheet.mission.id, timesheet.working_date.day)] = timesheet.charge
            if mission.id in timesheetTotal:
                timesheetTotal[mission.id] += timesheet.charge
            else:
                timesheetTotal[mission.id] = timesheet.charge
            totalPerDay[timesheet.working_date.day - 1] += timesheet.charge
    # Gather lunck ticket data
    totalTicket = 0
    lunchTickets = LunchTicket.objects.filter(consultant=consultant)
    lunchTickets = lunchTickets.filter(lunch_date__gte=month).filter(lunch_date__lt=next_month)
    for lunchTicket in lunchTickets:
        timesheetData["lunch_ticket_%s" % lunchTicket.lunch_date.day] = lunchTicket.no_ticket
        totalTicket += 1
    timesheetTotal["ticket"] = totalTicket
    # Compute warnings (overbooking and no data)
    for i in totalPerDay:
        i = round(i, 4)  # We must round because using keyboard time input may lead to real numbers that are truncated
        if i > 1:  # Surbooking
            warning.append(1)
        elif i == 1:  # Ok
            warning.append(0)
        else:  # warning (no data, or half day)
            warning.append(2)
    # Don't emit warning for no data during week ends and holidays
    holiday_days = holidayDays(month)
    for day in daysOfMonth(month):
        if day.isoweekday() in (6, 7) or day in holiday_days:
            warning[day.day - 1] = None

    return (timesheetData, timesheetTotal, warning)