def queue_service_class_reports(): from kardboard.app import app from kardboard.models import ServiceClassRecord, ServiceClassSnapshot from kardboard.util import now, month_ranges logger = queue_service_class_reports.get_logger() report_groups = app.config.get('REPORT_GROUPS', {}) group_slugs = report_groups.keys() group_slugs.append('all') for slug in group_slugs: logger.info("ServiceClassSnapshot: %s" % slug) ServiceClassSnapshot.calculate(slug) for x in [1, 3, 6, 9, 12]: start = now() months_ranges = month_ranges(start, x) start_date = months_ranges[0][0] end_date = months_ranges[-1][1] try: logger.info("ServiceClassRecord: %s %s - %s" % (slug, start_date, end_date)) ServiceClassRecord.calculate( start_date=start_date, end_date=end_date, group=slug, ) except Exception, e: msg = "ERROR: Couldn't calc record: %s / %s / %s" % \ (slug, start_date, end_date) log_exception(e, msg)
def report_detailed_flow(group="all", months=3, cards_only=False): end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) if cards_only: only_arg = ('state_card_counts', 'date', 'group') else: only_arg = ('state_counts', 'date', 'group') reports = FlowReport.objects.filter( date__gte=start_day, date__lte=end_day, group=group).only(*only_arg) if not reports: abort(404) chart = {} chart['categories'] = [] series = [] for state in States(): seri = {'name': state, 'data': []} series.append(seri) done_starting_point = 0 for report in reports: chart['categories'].append(report.date.strftime("%m/%d")) for seri in series: if cards_only: daily_seri_data = report.state_card_counts.get(seri['name'], 0) else: daily_seri_data = report.state_counts.get(seri['name'], 0) if seri['name'] == "Done": if len(seri['data']) == 0: done_starting_point = daily_seri_data daily_seri_data = 0 else: daily_seri_data = daily_seri_data - done_starting_point seri['data'].append(daily_seri_data) chart['series'] = series start_date = reports.order_by('date').first().date reports.order_by('-date') context = { 'title': "Detailed Cumulative Flow", 'reports': reports, 'months': months, 'cards_only': cards_only, 'chart': chart, 'start_date': start_date, 'updated_at': reports[0].updated_at, 'states': States(), 'version': VERSION, } return render_template('report-detailed-flow.html', **context)
def report_flow(group="all", months=3): end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) records = DailyRecord.objects.filter(date__gte=start_day, date__lte=end_day, group=group) chart = {} chart["categories"] = [report.date.strftime("%m/%d") for report in records] series = [{"name": "Planning", "data": []}, {"name": "Todo", "data": []}, {"name": "Done", "data": []}] for row in records: series[0]["data"].append(row.backlog) series[1]["data"].append(row.in_progress) series[2]["data"].append(row.done) chart["series"] = series start_date = records.order_by("date").first().date records.order_by("-date") context = { "title": "Cumulative Flow", "updated_at": datetime.datetime.now(), "chart": chart, "start_date": start_date, "flowdata": records, "version": VERSION, } return render_template("chart-flow.html", **context)
def report_throughput(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) month_counts = [] for arange in months_ranges: start, end = arange filtered_cards = Kard.objects.filter(done_date__gte=start, done_date__lte=end) rg = ReportGroup(group, filtered_cards) cards = rg.queryset num = cards.count() month_counts.append((start.strftime("%B"), num)) chart = {} chart["categories"] = [c[0] for c in month_counts] chart["series"] = [{"data": [c[1] for c in month_counts], "name": "Cards"}] context = { "title": "How much have we done?", "updated_at": datetime.datetime.now(), "chart": chart, "month_counts": month_counts, "version": VERSION, } return render_template("report-throughput.html", **context)
def chart_flow(group="all", months=3): end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) records = DailyRecord.objects.filter( date__gte=start_day, date__lte=end_day, group=group) chart = CumulativeFlowChart(900, 300) chart.add_data([r.backlog_cum for r in records]) chart.add_data([r.in_progress_cum for r in records]) chart.add_data([r.done for r in records]) chart.setup_grid(records) records.order_by('-date') context = { 'title': "Cumulative Flow", 'updated_at': datetime.datetime.now(), 'chart': chart, 'flowdata': records, 'version': VERSION, } return render_template('chart-flow.html', **context)
def report_service_class(group="all", months=None): from kardboard.app import app service_class_order = app.config.get("SERVICE_CLASSES", {}).keys() service_class_order.sort() service_classes = [app.config["SERVICE_CLASSES"][k] for k in service_class_order] if months is None: # We want the current report try: scr = ServiceClassSnapshot.objects.get(group=group) except ServiceClassSnapshot.DoesNotExist: scr = ServiceClassSnapshot.calculate(group=group) time_range = "current" else: start = now() months_ranges = month_ranges(start, months) start_date = months_ranges[0][0] end_date = months_ranges[-1][1] try: scr = ServiceClassRecord.objects.get(group=group, start_date=start_date, end_date=end_date) except ServiceClassRecord.DoesNotExist: scr = ServiceClassRecord.calculate(group=group, start_date=start_date, end_date=end_date) time_range = "past %s months" % months context = { "title": "Service classes: %s" % time_range, "service_classes": service_classes, "data": scr.data, "updated_at": scr.updated_at, "version": VERSION, } return render_template("report-service-class.html", **context)
def report_throughput(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) month_counts = [] for arange in months_ranges: start, end = arange filtered_cards = Kard.objects.filter(done_date__gte=start, done_date__lte=end) rg = ReportGroup(group, filtered_cards) cards = rg.queryset num = cards.count() month_counts.append((start.strftime("%B"), num)) chart = {} chart['categories'] = [c[0] for c in month_counts] chart['series'] = [{ 'data': [c[1] for c in month_counts], 'name': 'Cards', }] context = { 'title': "How much have we done?", 'updated_at': datetime.datetime.now(), 'chart': chart, 'month_counts': month_counts, 'version': VERSION, } return render_template('report-throughput.html', **context)
def chart_throughput(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) month_counts = [] for arange in months_ranges: start, end = arange filtered_cards = Kard.objects.filter(done_date__gte=start, done_date__lte=end) rg = ReportGroup(group, filtered_cards) cards = rg.queryset num = cards.count() month_counts.append((start.strftime("%B"), num)) chart = ThroughputChart(900, 300) chart.add_bars(month_counts) context = { 'title': "How much have we done?", 'updated_at': datetime.datetime.now(), 'chart': chart, 'month_counts': month_counts, 'version': VERSION, } return render_template('chart-throughput.html', **context)
def report_detailed_flow(group="all", months=3, cards_only=False): end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) if cards_only: only_arg = ('state_card_counts', 'date', 'group') else: only_arg = ('state_counts', 'date', 'group') reports = FlowReport.objects.filter(date__gte=start_day, date__lte=end_day, group=group).only(*only_arg) if not reports: abort(404) chart = {} chart['categories'] = [] series = [] for state in States(): seri = {'name': state, 'data': []} series.append(seri) done_starting_point = 0 for report in reports: chart['categories'].append(report.date.strftime("%m/%d")) for seri in series: if cards_only: daily_seri_data = report.state_card_counts.get(seri['name'], 0) else: daily_seri_data = report.state_counts.get(seri['name'], 0) if seri['name'] == "Done": if len(seri['data']) == 0: done_starting_point = daily_seri_data daily_seri_data = 0 else: daily_seri_data = daily_seri_data - done_starting_point seri['data'].append(daily_seri_data) chart['series'] = series start_date = reports.order_by('date').first().date reports.order_by('-date') context = { 'title': "Detailed Cumulative Flow", 'reports': reports, 'months': months, 'cards_only': cards_only, 'chart': chart, 'start_date': start_date, 'updated_at': reports[0].updated_at, 'states': States(), 'version': VERSION, } return render_template('report-detailed-flow.html', **context)
def report_efficiency(group="all", months=3): state_mappings = app.config.get("EFFICIENCY_MAPPINGS", None) if state_mappings is None: abort(404) stats = teams_service.EfficiencyStats(mapping=state_mappings) end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) records = FlowReport.objects.filter(date__gte=start_day, date__lte=end_day, group=group) incremented_state_counts = [] for r in records: a_record = {"date": r.date} a_record.update(r.state_counts) incremented_state_counts.append(a_record) for group_name in app.config.get("EFFICIENCY_INCREMENTS", ()): stats.make_incremental(incremented_state_counts, group_name) data = [] for r in incremented_state_counts: efficiency_stats = stats.calculate(r) data.append({"date": r["date"], "stats": efficiency_stats}) chart = {} chart["categories"] = [report.date.strftime("%m/%d") for report in records] group_names = app.config.get("EFFICIENCY_MAPPINGS_ORDER", state_mappings.keys()) series = [] for group_name in group_names: seri_data = [] for d in data: seri_data.append(d["stats"][group_name]) seri = dict(name=group_name, data=seri_data) series.append(seri) chart["series"] = series table_data = [] for row in data: table_row = {"Date": row["date"]} for group_name in group_names: table_row[group_name] = row["stats"][group_name] table_data.append(table_row) start_date = records.order_by("date").first().date context = { "title": "Efficiency", "start_date": start_date, "chart": chart, "table_data": table_data, "data_keys": ["Date"] + list(group_names), "updated_at": records.order_by("date")[len(records) - 1].date, "version": VERSION, } return render_template("chart-efficiency.html", **context)
def report_detailed_flow(group="all", months=3, cards_only=False): end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) if cards_only: only_arg = ("state_card_counts", "date", "group") else: only_arg = ("state_counts", "date", "group") reports = FlowReport.objects.filter(date__gte=start_day, date__lte=end_day, group=group).only(*only_arg) if not reports: abort(404) chart = {} chart["categories"] = [] series = [] for state in States(): seri = {"name": state, "data": []} series.append(seri) done_starting_point = 0 for report in reports: chart["categories"].append(report.date.strftime("%m/%d")) for seri in series: if cards_only: daily_seri_data = report.state_card_counts.get(seri["name"], 0) else: daily_seri_data = report.state_counts.get(seri["name"], 0) if seri["name"] == "Done": if len(seri["data"]) == 0: done_starting_point = daily_seri_data daily_seri_data = 0 else: daily_seri_data = daily_seri_data - done_starting_point seri["data"].append(daily_seri_data) chart["series"] = series start_date = reports.order_by("date").first().date reports.order_by("-date") context = { "title": "Detailed Cumulative Flow", "reports": reports, "months": months, "cards_only": cards_only, "chart": chart, "start_date": start_date, "updated_at": reports[0].updated_at, "states": States(), "version": VERSION, } return render_template("report-detailed-flow.html", **context)
def report_throughput(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) defect_types = app.config.get('DEFECT_TYPES', None) with_defects = defect_types is not None month_counts = [] for arange in months_ranges: start, end = arange filtered_cards = Kard.objects.filter(done_date__gte=start, done_date__lte=end) rg = ReportGroup(group, filtered_cards) cards = rg.queryset if with_defects: counts = {'card': 0, 'defect': 0} for card in cards: if card.type.strip() in defect_types: counts['defect'] += 1 else: counts['card'] += 1 month_counts.append((start.strftime("%B '%y"), counts)) else: num = cards.count() month_counts.append((start.strftime("%B, '%y"), num)) chart = {} chart['categories'] = [c[0] for c in month_counts] if with_defects: chart['series'] = [ { 'data': [c[1]['card'] for c in month_counts], 'name': 'Cards' }, { 'data': [c[1]['defect'] for c in month_counts], 'name': 'Defects' } ] else: chart['series'] = [{ 'data': [c[1] for c in month_counts], 'name': 'Cards', }] context = { 'title': "How much have we done?", 'updated_at': datetime.datetime.now(), 'chart': chart, 'month_counts': month_counts, 'version': VERSION, 'with_defects': with_defects, } return render_template('report-throughput.html', **context)
def report_throughput(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) defect_types = app.config.get('DEFECT_TYPES', None) with_defects = defect_types is not None month_counts = [] for arange in months_ranges: start, end = arange filtered_cards = Kard.objects.filter(done_date__gte=start, done_date__lte=end) rg = ReportGroup(group, filtered_cards) cards = rg.queryset if with_defects: counts = {'card': 0, 'defect': 0} for card in cards: if card.type.strip() in defect_types: counts['defect'] += 1 else: counts['card'] += 1 month_counts.append((start.strftime("%B"), counts)) else: num = cards.count() month_counts.append((start.strftime("%B"), num)) chart = {} chart['categories'] = [c[0] for c in month_counts] if with_defects: chart['series'] = [ { 'data': [c[1]['card'] for c in month_counts], 'name': 'Cards' }, { 'data': [c[1]['defect'] for c in month_counts], 'name': 'Defects' } ] else: chart['series'] = [{ 'data': [c[1] for c in month_counts], 'name': 'Cards', }] context = { 'title': "How much have we done?", 'updated_at': datetime.datetime.now(), 'chart': chart, 'month_counts': month_counts, 'version': VERSION, 'with_defects': with_defects, } return render_template('report-throughput.html', **context)
def report_leaderboard(group="all", months=3, person=None, start_month=None, start_year=None): start = datetime.datetime.today() if start_month and start_year: start = start.replace(month=start_month, year=start_year) months_ranges = month_ranges(start, months) start = months_ranges[0][0] end = months_ranges[-1][-1] rg = ReportGroup(group, Kard.objects.done()) done = rg.queryset cards = done.filter(done_date__gte=start, done_date__lte=end) people = {} for card in cards: try: devs = card.ticket_system_data['developers'] for d in devs: p = people.get(d, PersonCardSet(d)) p.add_card(card) people[d] = p except KeyError: pass if person: person = people.get(person, None) people = [] if not person: abort(404) else: people = people.values() people.sort(reverse=True) context = { 'people': people, 'person': person, 'months': months, 'group': group, 'start': start, 'end': end, 'start_month': start_month, 'start_year': start_year, 'title': "Developer Leaderboard", 'updated_at': datetime.datetime.now(), 'version': VERSION, } if person: context['title'] = "%s: %s" % (person.name, context['title']) return render_template('leaderboard.html', **context)
def report_service_class(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) rg = ReportGroup(group, Kard.objects) rg_cards = rg.queryset classes = rg_cards.distinct('service_class') classes.sort() datatable = { 'headers': ('Month', 'Class', 'Throughput', 'Cycle Time', 'Lead Time'), 'rows': [], } months = [] for arange in months_ranges: for cls in classes: row = [] start, end = arange filtered_cards = Kard.objects.filter(done_date__gte=start, done_date__lte=end, _service_class=cls) rg = ReportGroup(group, filtered_cards) cards = rg.queryset if cards.count() == 0: # We don't need to have rows for # service classes we didn't do continue month_name = start.strftime("%B") if month_name not in months: row.append(month_name) months.append(month_name) else: row.append('') row.append(cls) row.append(cards.count()) if cards.count() > 0: row.append("%d" % cards.average('_cycle_time')) row.append("%d" % cards.average('_lead_time')) else: row.append('N/A') row.append('N/A') row = tuple(row) datatable['rows'].append(row) context = { 'title': "By service class", 'updated_at': datetime.datetime.now(), 'datatable': datatable, 'version': VERSION, } return render_template('report-classes.html', **context)
def report_service_class(group="all", months=None): from kardboard.app import app service_class_order = app.config.get('SERVICE_CLASSES', {}).keys() service_class_order.sort() service_classes = [ app.config['SERVICE_CLASSES'][k] for k in service_class_order ] if months is None: # We want the current report try: scr = ServiceClassSnapshot.objects.get( group=group, ) except ServiceClassSnapshot.DoesNotExist: scr = ServiceClassSnapshot.calculate( group=group, ) time_range = 'current' start_date = make_start_date(date=datetime.datetime.now()) end_date = make_end_date(date=datetime.datetime.now()) else: start = now() months_ranges = month_ranges(start, months) start_date = months_ranges[0][0] end_date = months_ranges[-1][1] try: scr = ServiceClassRecord.objects.get( group=group, start_date=start_date, end_date=end_date, ) except ServiceClassRecord.DoesNotExist: scr = ServiceClassRecord.calculate( group=group, start_date=start_date, end_date=end_date, ) time_range = 'past %s months' % months context = { 'title': "Service classes: %s" % time_range, 'service_classes': service_classes, 'data': scr.data, 'start_date': start_date, 'end_date': end_date, 'updated_at': scr.updated_at, 'version': VERSION, } return render_template('report-service-class.html', **context)
def report_leaderboard(group="all", months=3, person=None, start_month=None, start_year=None): start = datetime.datetime.today() if start_month and start_year: start = start.replace(month=start_month, year=start_year) months_ranges = month_ranges(start, months) start = months_ranges[0][0] end = months_ranges[-1][-1] rg = ReportGroup(group, Kard.objects.done()) done = rg.queryset cards = done.filter(done_date__gte=start, done_date__lte=end) people = {} for card in cards: try: devs = card.ticket_system_data["developers"] for d in devs: p = people.get(d, PersonCardSet(d)) p.add_card(card) people[d] = p except KeyError: pass if person: person = people.get(person, None) people = [] if not person: abort(404) else: people = people.values() people.sort(reverse=True) context = { "people": people, "person": person, "months": months, "group": group, "start": start, "end": end, "start_month": start_month, "start_year": start_year, "title": "Developer Leaderboard", "updated_at": datetime.datetime.now(), "version": VERSION, } if person: context["title"] = "%s: %s" % (person.name, context["title"]) return render_template("leaderboard.html", **context)
def done(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) start = months_ranges[0][0] end = months_ranges[-1][-1] rg = ReportGroup(group, Kard.objects.done()) done = rg.queryset cards = done.filter(done_date__gte=start, done_date__lte=end).order_by("-done_date") context = {"title": "Completed Cards", "cards": cards, "updated_at": datetime.datetime.now(), "version": VERSION} return render_template("done.html", **context)
def report_types(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) rg = ReportGroup(group, Kard.objects) rg_cards = rg.queryset types = list(rg_cards.distinct('_type')) types.sort() datatable = { 'headers': ('Month', 'Type', 'Throughput', 'Cycle Time', 'Lead Time'), 'rows': [], } months = [] for arange in months_ranges: for typ in types: row = [] start, end = arange filtered_cards = Kard.objects.filter(done_date__gte=start, done_date__lte=end, _type=typ) rg = ReportGroup(group, filtered_cards) cards = rg.queryset if cards.count() > 0: month_name = start.strftime("%B") if month_name not in months: row.append(month_name) months.append(month_name) else: row.append('') row.append(typ) row.append(cards.count()) row.append("%d" % cards.average('_cycle_time')) row.append("%d" % cards.average('_lead_time')) if row: row = tuple(row) datatable['rows'].append(row) context = { 'title': "By type", 'updated_at': datetime.datetime.now(), 'datatable': datatable, 'version': VERSION, } return render_template('report-types.html', **context)
def report_service_class(group="all", months=None): from kardboard.app import app service_class_order = app.config.get('SERVICE_CLASSES', {}).keys() service_class_order.sort() service_classes = [ app.config['SERVICE_CLASSES'][k] for k in service_class_order ] if months is None: # We want the current report try: scr = ServiceClassSnapshot.objects.get(group=group, ) except ServiceClassSnapshot.DoesNotExist: scr = ServiceClassSnapshot.calculate(group=group, ) time_range = 'current' start_date = make_start_date(date=datetime.datetime.now()) end_date = make_end_date(date=datetime.datetime.now()) else: start = now() months_ranges = month_ranges(start, months) start_date = months_ranges[0][0] end_date = months_ranges[-1][1] try: scr = ServiceClassRecord.objects.get( group=group, start_date=start_date, end_date=end_date, ) except ServiceClassRecord.DoesNotExist: scr = ServiceClassRecord.calculate( group=group, start_date=start_date, end_date=end_date, ) time_range = 'past %s months' % months context = { 'title': "Service classes: %s" % time_range, 'service_classes': service_classes, 'data': scr.data, 'start_date': start_date, 'end_date': end_date, 'updated_at': scr.updated_at, 'version': VERSION, } return render_template('report-service-class.html', **context)
def report_throughput(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) defect_types = app.config.get("DEFECT_TYPES", None) with_defects = defect_types is not None month_counts = [] for arange in months_ranges: start, end = arange filtered_cards = Kard.objects.filter(done_date__gte=start, done_date__lte=end) rg = ReportGroup(group, filtered_cards) cards = rg.queryset if with_defects: counts = {"card": 0, "defect": 0} for card in cards: if card.type.strip() in defect_types: counts["defect"] += 1 else: counts["card"] += 1 month_counts.append((start.strftime("%B"), counts)) else: num = cards.count() month_counts.append((start.strftime("%B"), num)) chart = {} chart["categories"] = [c[0] for c in month_counts] if with_defects: chart["series"] = [ {"data": [c[1]["card"] for c in month_counts], "name": "Cards"}, {"data": [c[1]["defect"] for c in month_counts], "name": "Defects"}, ] else: chart["series"] = [{"data": [c[1] for c in month_counts], "name": "Cards"}] context = { "title": "How much have we done?", "updated_at": datetime.datetime.now(), "chart": chart, "month_counts": month_counts, "version": VERSION, "with_defects": with_defects, } return render_template("report-throughput.html", **context)
def report_flow(group="all", months=3): end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) records = DailyRecord.objects.filter(date__gte=start_day, date__lte=end_day, group=group) chart = {} chart['categories'] = [report.date.strftime("%m/%d") for report in records] series = [ { 'name': "Planning", 'data': [] }, { 'name': "Todo", 'data': [] }, { 'name': "Done", 'data': [] }, ] for row in records: series[0]['data'].append(row.backlog) series[1]['data'].append(row.in_progress) series[2]['data'].append(row.done) chart['series'] = series start_date = records.order_by('date').first().date records.order_by('-date') context = { 'title': "Cumulative Flow", 'updated_at': datetime.datetime.now(), 'chart': chart, 'start_date': start_date, 'flowdata': records, 'version': VERSION, } return render_template('chart-flow.html', **context)
def report_service_class(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) rg = ReportGroup(group, Kard.objects) rg_cards = rg.queryset classes = rg_cards.distinct("service_class") classes.sort() datatable = {"headers": ("Month", "Class", "Throughput", "Cycle Time", "Lead Time"), "rows": []} months = [] for arange in months_ranges: for cls in classes: row = [] start, end = arange filtered_cards = Kard.objects.filter(done_date__gte=start, done_date__lte=end, _service_class=cls) rg = ReportGroup(group, filtered_cards) cards = rg.queryset if cards.count() > 0: month_name = start.strftime("%B") if month_name not in months: row.append(month_name) months.append(month_name) else: row.append("") row.append(cls) row.append(cards.count()) row.append("%d" % cards.average("_cycle_time")) row.append("%d" % cards.average("_lead_time")) if row: row = tuple(row) datatable["rows"].append(row) context = { "title": "By service class", "updated_at": datetime.datetime.now(), "datatable": datatable, "version": VERSION, } return render_template("report-classes.html", **context)
def done(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) start = months_ranges[0][0] end = months_ranges[-1][-1] rg = ReportGroup(group, Kard.objects.done()) done = rg.queryset cards = done.filter(done_date__gte=start, done_date__lte=end).order_by('-done_date') context = { 'title': "Completed Cards", 'cards': cards, 'updated_at': datetime.datetime.now(), 'version': VERSION, } return render_template('done.html', **context)
def report_detailed_flow(group="all", months=3): end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) reports = FlowReport.objects.filter(date__gte=start_day, date__lte=end_day, group=group) if not reports: abort(404) chart = {} chart["categories"] = [] series = [] for state in States(): seri = {"name": state, "data": []} series.append(seri) for report in reports: chart["categories"].append(report.date.strftime("%m/%d")) for seri in series: daily_seri_data = report.snapshot.get(seri["name"], {}).get("count", 0) seri["data"].append(daily_seri_data) chart["series"] = series start_date = reports.order_by("date").first().date reports.order_by("-date") context = { "title": "Detailed Cumulative Flow", "reports": reports, "months": months, "chart": chart, "start_date": start_date, "updated_at": reports[0].updated_at, "states": States(), "version": VERSION, } return render_template("report-detailed-flow.html", **context)
def blocked(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) start = months_ranges[0][0] end = months_ranges[-1][-1] rg = ReportGroup(group, Kard.objects()) blocked_cards = rg.queryset blocked_cards = blocked_cards.filter(start_date__gte=start, start_date__lte=end, blocked_ever=True).order_by('-start_date') context = { 'title': "Blocked", 'cards': blocked_cards, 'start': start, 'end': end, 'updated_at': datetime.datetime.now(), 'version': VERSION, } return render_template('blocked.html', **context)
def blocked(group="all", months=3, start=None): start = start or datetime.datetime.today() months_ranges = month_ranges(start, months) start = months_ranges[0][0] end = months_ranges[-1][-1] rg = ReportGroup(group, Kard.objects()) blocked_cards = rg.queryset blocked_cards = blocked_cards.filter( start_date__gte=start, start_date__lte=end, blocked_ever=True).order_by('-start_date') context = { 'title': "Blocked", 'cards': blocked_cards, 'start': start, 'end': end, 'updated_at': datetime.datetime.now(), 'version': VERSION, } return render_template('blocked.html', **context)
def report_flow(group="all", months=3): end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) records = DailyRecord.objects.filter( date__gte=start_day, date__lte=end_day, group=group) chart = {} chart['categories'] = [report.date.strftime("%m/%d") for report in records] series = [ {'name': "Planning", 'data': []}, {'name': "Todo", 'data': []}, {'name': "Done", 'data': []}, ] for row in records: series[0]['data'].append(row.backlog) series[1]['data'].append(row.in_progress) series[2]['data'].append(row.done) chart['series'] = series start_date = records.order_by('date').first().date records.order_by('-date') context = { 'title': "Cumulative Flow", 'updated_at': datetime.datetime.now(), 'chart': chart, 'start_date': start_date, 'flowdata': records, 'version': VERSION, } return render_template('chart-flow.html', **context)
def report_efficiency(group="all", months=3): state_mappings = app.config.get('EFFICIENCY_MAPPINGS', None) if state_mappings is None: abort(404) stats = teams_service.EfficiencyStats(mapping=state_mappings) end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) records = FlowReport.objects.filter( date__gte=start_day, date__lte=end_day, group=group ) incremented_state_counts = [] for r in records: a_record = {'date': r.date} a_record.update(r.state_counts) incremented_state_counts.append(a_record) for group_name in app.config.get('EFFICIENCY_INCREMENTS', ()): stats.make_incremental(incremented_state_counts, group_name) data = [] for r in incremented_state_counts: efficiency_stats = stats.calculate(r) data.append( {'date': r['date'], 'stats': efficiency_stats} ) chart = {} chart['categories'] = [report.date.strftime("%m/%d") for report in records] group_names = app.config.get('EFFICIENCY_MAPPINGS_ORDER', state_mappings.keys()) series = [] for group_name in group_names: seri_data = [] for d in data: seri_data.append(d['stats'][group_name]) seri = dict(name=group_name, data=seri_data) series.append(seri) chart['series'] = series table_data = [] for row in data: table_row = {'Date': row['date']} for group_name in group_names: table_row[group_name] = row['stats'][group_name] table_data.append(table_row) start_date = records.order_by('date').first().date context = { 'title': "Efficiency", 'start_date': start_date, 'chart': chart, 'table_data': table_data, 'data_keys': ['Date', ] + list(group_names), 'updated_at': records.order_by('date')[len(records) - 1].date, 'version': VERSION, } return render_template('chart-efficiency.html', **context)
def report_efficiency(group="all", months=3): state_mappings = app.config.get('EFFICIENCY_MAPPINGS', None) if state_mappings is None: abort(404) stats = teams_service.EfficiencyStats(mapping=state_mappings) end = kardboard.util.now() months_ranges = month_ranges(end, months) start_day = make_start_date(date=months_ranges[0][0]) end_day = make_end_date(date=end) records = FlowReport.objects.filter(date__gte=start_day, date__lte=end_day, group=group) incremented_state_counts = [] for r in records: a_record = {'date': r.date} a_record.update(r.state_counts) incremented_state_counts.append(a_record) for group_name in app.config.get('EFFICIENCY_INCREMENTS', ()): stats.make_incremental(incremented_state_counts, group_name) data = [] for r in incremented_state_counts: efficiency_stats = stats.calculate(r) data.append({'date': r['date'], 'stats': efficiency_stats}) chart = {} chart['categories'] = [report.date.strftime("%m/%d") for report in records] group_names = app.config.get('EFFICIENCY_MAPPINGS_ORDER', state_mappings.keys()) series = [] for group_name in group_names: seri_data = [] for d in data: seri_data.append(d['stats'][group_name]) seri = dict(name=group_name, data=seri_data) series.append(seri) chart['series'] = series table_data = [] for row in data: table_row = {'Date': row['date']} for group_name in group_names: table_row[group_name] = row['stats'][group_name] table_data.append(table_row) start_date = records.order_by('date').first().date context = { 'title': "Efficiency", 'start_date': start_date, 'chart': chart, 'table_data': table_data, 'data_keys': [ 'Date', ] + list(group_names), 'updated_at': records.order_by('date')[len(records) - 1].date, 'version': VERSION, } return render_template('chart-efficiency.html', **context)