def report_for_account(account, now, send=True):
    '''Sends all overtime reports to the managers of an account for a given
    date.'''
    DAYS_SHORT = [element[0]
                  for element in WORKING_CHOICES
                  if element[0] != "SATUR"] + ["ROVER"]
    buff = StringIO()
    buff.write("\xef\xbb\xbf")
    csvout = UnicodeWriter(buff, delimiter=';')
    users = Tbluser.objects.filter(market=account, disabled=False).order_by("lastname")

    # generate the dates for this month
    c = calendar.Calendar()
    dates = filter(
    lambda date: date.month == now.month,
    c.itermonthdates(now.year, now.month)
    )

    csvout.writerow(
        # write out the top heading
        ["Date"] + [user.rev_name() for user in users]
        )
    csvout.writerow(
        # write out the settlement period row.
        ["Settlement Period"] + [user.job_code[-1]
                                 if user.job_code else ""
                                 for user in users]
        )
    csvout.writerow(
        # write out the e-mail row.
        ["EmployeeID"] + [user.user_id for user in users]
        )
    csvout.writerow(
        # write out the total balances.
        ["Balance"] + ['="'+str(user.get_total_balance(ret='flo',
                                                       year=now.year,month=now.month))+'"'
                       for user in users]
        )
    for date in dates:
        current_line = [str(date)]
        for user in users:
            try:
                entry = TrackingEntry.objects.get(
                    user_id=user.id,
                    entry_date=date
                )
            except TrackingEntry.DoesNotExist:
                current_line.append("")
                continue
            if entry.daytype not in DAYS_SHORT:
                current_line.append("")
                continue
            if entry.is_linked():
                current_line.append("")
                continue
            # if the entry is a return for overtime entry, we display
            # the user's shiftlength as a negative value since that's
            # what the value should be.
            value = round_down(entry.time_difference() if entry.daytype != "ROVER" else -entry.total_working_time())
            current_line.append('="'+str(value)+'"' if value != 0 else "")
        csvout.writerow(current_line)

    csvfile = buff.getvalue()
    if send:
        message = mail.EmailMessage(from_email="*****@*****.**")
        message.body = \
                       "Hi,\n\n" \
                       "Please see attached your month end overtime report for " \
                       "your team.\n\n" \
                       "If there are any errors, please inform the administrator " \
                       "of the timetracker immediately.\n\n" \
                       "Regards,\n" \
                       "Timetracker team"

        message.attach(
            "overtimereport.csv",
            csvfile,
            "application/octet-stream"
        )
        message.to = ["*****@*****.**"] + \
                     Tbluser.administrator_emails_for_account(account)
        message.subject = "End of month Overtime Totals."
        message.send()
    else:
        response = HttpResponse(csvfile, mimetype="text/csv")
        response['Content-Disposition'] = \
            'attachment;filename=MEC_OT_Report_%s.csv' % now
        return response
def send_report_for_account(account, now):
    '''Sends all overtime reports to the managers of an account for a given
    date.'''
    message = mail.EmailMessage(from_email="*****@*****.**")
    message.body = \
        "Hi,\n\n" \
        "Please see attached your month end overtime report for " \
        "your team.\n\n" \
        "If there are any errors, please inform the administrator " \
        "of the timetracker immediately.\n\n" \
        "Regards,\n" \
        "Timetracker team"

    buff = StringIO()
    buff.write("\xef\xbb\xbf")
    csvout = UnicodeWriter(buff, delimiter=';')
    users = filter(
        lambda user: user.get_total_balance(ret='num') == 0,
        Tbluser.objects.filter(market=account, disabled=False)
        )

    # generate the dates for this month
    c = calendar.Calendar()
    dates = filter(
    lambda date: date.month == now.month,
    c.itermonthdates(now.year, now.month)
    )
    csvout.writerow(
        # write out the top heading
        ["Date"] + [user.rev_name() for user in users]
        )
    csvout.writerow(
        # write out the settlement period row.
        ["Settlement Period"] + [user.job_code[-1]
                                 if user.job_code else ""
                                 for user in users]
        )
    csvout.writerow(
        # write out the e-mail row.
        ["EmployeeID"] + [user.user_id for user in users]
        )
    csvout.writerow(
        # write out the total balances.
        ["Balance"] + [str(user.get_total_balance(ret='num'))
                       for user in users]
        )
    for date in dates:
        current_line = [str(date)]
        for user in users:
            try:
                entry = TrackingEntry.objects.get(user_id=user.id,
                                                  entry_date=date)
            except TrackingEntry.DoesNotExist:
                current_line.append("")
                continue

            if entry.is_overtime():
                current_line.append(0-entry.time_difference())
            else:
                current_line.append("")
        csvout.writerow(current_line)

    csvfile = buff.getvalue()
    message.attach(
        "overtimereport.csv",
        csvfile,
        "application/octet-stream"
        )
    message.to = ["*****@*****.**"] + \
        Tbluser.administrator_emails_for_account(account)
    message.subject = "End of month Overtime Totals."
    message.send()
Exemple #3
0
def report_for_account(account, now, send=True):
    '''Sends all overtime reports to the managers of an account for a given
    date.'''
    DAYS_SHORT = [
        element[0] for element in WORKING_CHOICES if element[0] != "SATUR"
    ] + ["ROVER"]
    buff = StringIO()
    buff.write("\xef\xbb\xbf")
    csvout = UnicodeWriter(buff, delimiter=';')
    users = Tbluser.objects.filter(market=account,
                                   disabled=False).order_by("lastname")

    # generate the dates for this month
    c = calendar.Calendar()
    dates = filter(lambda date: date.month == now.month,
                   c.itermonthdates(now.year, now.month))

    csvout.writerow(
        # write out the top heading
        ["Date"] + [user.rev_name() for user in users])
    csvout.writerow(
        # write out the settlement period row.
        ["Settlement Period"] +
        [user.job_code[-1] if user.job_code else "" for user in users])
    csvout.writerow(
        # write out the e-mail row.
        ["EmployeeID"] + [user.user_id for user in users])
    csvout.writerow(
        # write out the total balances.
        ["Balance"] + [
            '="' + str(
                user.get_total_balance(
                    ret='flo', year=now.year, month=now.month)) + '"'
            for user in users
        ])
    for date in dates:
        current_line = [str(date)]
        for user in users:
            try:
                entry = TrackingEntry.objects.get(user_id=user.id,
                                                  entry_date=date)
            except TrackingEntry.DoesNotExist:
                current_line.append("")
                continue
            if entry.daytype not in DAYS_SHORT:
                current_line.append("")
                continue
            if entry.is_linked():
                current_line.append("")
                continue
            # if the entry is a return for overtime entry, we display
            # the user's shiftlength as a negative value since that's
            # what the value should be.
            value = round_down(entry.time_difference(
            ) if entry.daytype != "ROVER" else -entry.total_working_time())
            current_line.append('="' + str(value) + '"' if value != 0 else "")
        csvout.writerow(current_line)

    csvfile = buff.getvalue()
    if send:
        message = mail.EmailMessage(from_email="*****@*****.**")
        message.body = \
                       "Hi,\n\n" \
                       "Please see attached your month end overtime report for " \
                       "your team.\n\n" \
                       "If there are any errors, please inform the administrator " \
                       "of the timetracker immediately.\n\n" \
                       "Regards,\n" \
                       "Timetracker team"

        message.attach("overtimereport.csv", csvfile,
                       "application/octet-stream")
        message.to = ["*****@*****.**"] + \
                     Tbluser.administrator_emails_for_account(account)
        message.subject = "End of month Overtime Totals."
        message.send()
    else:
        response = HttpResponse(csvfile, mimetype="text/csv")
        response['Content-Disposition'] = \
            'attachment;filename=MEC_OT_Report_%s.csv' % now
        return response
    def utilization_calculation(teams, year=None, month=None):
        if year is None: # pragma: no cover
            year = datetime.today().year
        if month is None: # pragma: no cover
            month = datetime.today().month

        cached_result = cache.get("utilization:%s%s%s" % (''.join(teams), year, month))
        if cached_result: # pragma: no cover
            return cached_result

        # prevent circular imports
        from timetracker.utils.calendar_utils import working_days
        from timetracker.tracker.models import Tbluser, TrackingEntry

        entries, invalid = ActivityEntry.filterforyearmonth(teams, year, month)
        if len(entries) == 0:
            return {
                "util": {
                    "percent": 0,
                    "target": 65
                },
                "effi": {
                    "percent": 0,
                    "target": 85
                },
                "avai": {
                    "percent": 0,
                    "target": 80
                },
                "FTE": 0
            }

        effi, util = (0, 0)
        users = set()
        losses = TrackingEntry.objects.filter(user__market__in=teams,
                                              daytype=["PUABS", "DAYOD", "HOLIS"],
                                              entry_date__year=year,
                                              # 460 is a single
                                              # industrial engineering
                                              # FTE in Minutes.
                                              entry_date__month=month).count() * 460
        for entry in entries:
            if invalid(entry): # pragma: no cover
                continue
            time = entry.amount * entry.activity.time
            if entry.activity.group != "ALL":
                util += time
            else: # pragma: no cover
                losses += time
            effi += time

            # so we can see how many FTE's we had during this month.
            users.add(entry.user)

        available_time = (Tbluser.available_minutes(teams) * len(working_days(year, month)))
        utilization_percent = (100 * (Decimal(util) / Decimal(available_time)))
        efficiency_percent = (100 * (Decimal(util) / (Decimal(available_time) - Decimal(losses))))
        availability_percent = (100 * (Decimal(available_time) - Decimal(losses)) / Decimal(available_time))

        res = {
            "util": {
                "percent": utilization_percent,
                "target": 65
            },
            "effi": {
                "percent": efficiency_percent,
                "target": 85
            },
            "avai": {
                "percent": availability_percent,
                "target": 80
            },
            "FTE": len(users)
        }
        cache.set("utilization:%s%s%s" % (''.join(teams), year, month), res)
        return res