def reporting_orgs_summary():
    reporting_orgs = qorganisations.get_reporting_orgs()
    response_statuses = [
        resp.as_dict() for resp in qmonitoring.response_statuses()
    ]
    orgs = generate_reporting_organisation_checklist(reporting_orgs,
                                                     response_statuses)

    def generate_summary(list_of_quarters, orgs):
        out = dict(
            map(lambda q: (q, {
                'True': 0,
                'False': 0,
                "Total": 0
            }), list_of_quarters.keys()))
        for ro in orgs:
            for disb_q, disb_v in ro["disbursements"].items():
                if disb_v["status"]["name"] == "Donor responded with data":
                    out[disb_q]['True'] += 1
                else:
                    out[disb_q]['False'] += 1
                out[disb_q]["Total"] += 1
        return out

    list_of_quarters = util.Last4Quarters().list_of_quarters()
    summary = generate_summary(list_of_quarters, orgs)

    return jsonify(summary=summary,
                   current_year=util.FY("current").fy_fy(),
                   previous_year=util.FY("previous").fy_fy(),
                   list_of_quarters=list_of_quarters)
Beispiel #2
0
def counterpart_funding():
    next_fy = util.FY("current").fiscal_year.name
    fiscal_year = request.args.get("fiscal_year", next_fy)
    start_date, end_date = qactivity.get_earliest_latest_dates_filter(
        {'key': 'domestic_external', 'val': 'external'})
    next_fy_end_date = util.FY("next").date("end")
    fys = [str(fy) for fy in util.fys_in_date_range(
        start_date, max(end_date, next_fy_end_date))]

    def annotate_activity(activity):
        return {
            'id': activity.id,
            'title': activity.title,
            'reporting_org_name': activity.reporting_org.name,
            'sector_name': ", ".join([sector.codelist_code.name for sector in activity.classification_data.get('mtef-sector', {}).get('entries', [])]),
            'ministry_name': ", ".join([ministry.codelist_code.name for ministry in activity.classification_data.get('aligned-ministry-agency', {}).get('entries', [])]),
            'gol_requested': activity._fy_counterpart_funding,
            'donor_planned': activity._fy_forwardspends
        }

    activities = [annotate_activity(activity) for activity in
        qcounterpart_funding.annotate_activities_with_aggregates(fiscal_year)]

    return jsonify(
        fy=util.FY("next").fy_fy(),
        activities=activities,
        fiscalYears=fys,
        fiscalYear=str(fiscal_year)
    )
def fwddata_query(current_previous="current"):
    since = util.FY(current_previous).date("start")
    until = util.FY(current_previous).date("end")
    return db.session.query(
        func.sum(models.ActivityForwardSpend.value).label("value"),
        models.Activity.reporting_org_id).join(models.Activity).filter(
            models.ActivityForwardSpend.value != 0).filter(
                models.ActivityForwardSpend.period_start_date >= since).filter(
                    models.ActivityForwardSpend.period_end_date <= until
                ).group_by(models.Activity.reporting_org_id).order_by(
                    models.Activity.reporting_org_id.desc()).all()
def reporting_orgs():
    reporting_orgs = qorganisations.get_reporting_orgs()
    response_statuses = [
        resp.as_dict() for resp in qmonitoring.response_statuses()
    ]
    orgs = generate_reporting_organisation_checklist(reporting_orgs,
                                                     response_statuses)
    return jsonify(orgs=orgs,
                   previous_year=util.FY("previous").fy_fy(),
                   current_year=util.FY("current").fy_fy(),
                   next_year=util.FY("next").fy_fy(),
                   list_of_quarters=util.Last4Quarters().list_of_quarters())
def reporting_orgs_user():
    if request.method == "POST":
        if ("organisation_id" in request.json) and ("response_id"
                                                    in request.json):
            qmonitoring.update_organisation_response(request.json)
        return jsonify(result=True)
    #FIXME change to roles
    if ("user_id" in request.args) or ("admin" not in current_user.roles_list):
        reporting_orgs = qorganisations.get_reporting_orgs(
            user_id=request.args.get('user_id', current_user.id))
        user = models.User.query.get(
            request.args.get('user_id', current_user.id))
        user_name = user.name
        user_id = user.id
    else:
        reporting_orgs = qorganisations.get_reporting_orgs()
        user_name = None
        user_id = None
    if "admin" in current_user.roles_list:
        users = [{
            'value': user.id,
            'text': user.name
        } for user in quser.users_with_role('desk-officer')]
    else:
        users = []
    response_statuses = [
        resp.as_dict() for resp in qmonitoring.response_statuses()
    ]
    orgs = generate_reporting_organisation_checklist(reporting_orgs,
                                                     response_statuses)

    data_collection_calendar = qmonitoring.generate_data_collection_calendar()

    return jsonify(orgs=orgs,
                   previous_year=util.FY("previous").fy_fy(),
                   current_year=util.FY("current").fy_fy(),
                   next_year=util.FY("next").fy_fy(),
                   list_of_quarters=util.Last4Quarters().list_of_quarters(),
                   users=users,
                   user_name=user_name,
                   user_id=user_id,
                   statuses=response_statuses,
                   data_collection_calendar=data_collection_calendar)
Beispiel #6
0
def available_fys_fqs():
    def mtef_or_disbursements():
        """Set reporting functionality to highlight MTEF or disbursement
        data import by default, depending on where we are in the year"""
        budget_preparation_month = 2
        if datetime.datetime.utcnow().date().month == budget_preparation_month:
            return "mtef"
        else:
            return "disbursements"

    return jsonify(fys=util.available_fys(),
                   fys_fqs=util.available_fy_fqs_as_dict(),
                   current_fy=util.FY("current").fy_fy(),
                   previous_fy_fq=util.previous_fy_fq(),
                   mtef_or_disbursements=mtef_or_disbursements())
Beispiel #7
0
def project_development_tracking():
    current_fy = util.FY("previous").fiscal_year.name
    fiscal_year = request.args.get("fiscal_year", current_fy)
    activities = models.Activity.query.filter_by(
        domestic_external="domestic"
    ).all()
    milestones = models.Milestone.query.filter_by(
        domestic_external="domestic"
    ).order_by(
        models.Milestone.milestone_order
    ).all()

    sum_appropriations = qreports.sum_transactions(
        fiscal_year, 0, 'domestic', 'sum_appropriations', 'C')
    sum_allotments = qreports.sum_transactions(
        fiscal_year, 0, 'domestic', 'sum_allotments', '99-A')
    sum_disbursements = qreports.sum_transactions(
        fiscal_year, 0, 'domestic', 'sum_disbursements', 'D')

    def annotate_activity(activity):
        out = OrderedDict({
            'id': activity.id,
            'title': activity.title,
            'implementer': ", ".join(
                [implementer.name for implementer in activity.implementing_organisations]
            ),
            'sum_appropriations': sum_appropriations.get(activity.id, 0.00),
            'sum_allotments': sum_allotments.get(activity.id, 0.00),
            'sum_disbursements': sum_disbursements.get(activity.id, 0.00)
        })
        [out.update({ms['name']: ms['achieved']})
         for ms in activity.milestones_data]
        return out

    milestone_data = [annotate_activity(activity) for activity in activities]

    start_date, end_date = qactivity.get_earliest_latest_dates_filter(
        {'key': 'domestic_external', 'val': 'domestic'})
    if start_date is not None:
        fys = [str(fy) for fy in util.fys_in_date_range(start_date, end_date)]
    else:
        fys = []

    return jsonify(activities=milestone_data,
                   milestones=[milestone.name for milestone in milestones],
                   fiscalYears=fys,
                   fiscalYear=str(fiscal_year))
Beispiel #8
0
def aid_disbursements_api():
    _current_fy = util.FY("previous")
    current_fy = _current_fy.fiscal_year.name
    fiscal_year = request.args.get("fiscal_year", current_fy)
    start_of_fy = _current_fy.fiscal_year.start
    days_since_fy_began = (
        (datetime.datetime.utcnow().date()-start_of_fy).days)
    progress_time = min(round(days_since_fy_began/365.0*100.0, 2), 100.0)
    start_date, end_date = qactivity.get_earliest_latest_dates_filter(
        {'key': 'domestic_external', 'val': 'external'})
    start_date = max(start_date, current_app.config['EARLIEST_DATE'])
    fys = [str(fy) for fy in util.fys_in_date_range(start_date, end_date)]

    return jsonify(activities=qreports.make_forwardspends_disbursements_data(fiscal_year),
                   progress_time=progress_time,
                   days_since_fy_began=days_since_fy_began,
                   fy_start_day=datetime.datetime.strftime(
                       start_of_fy, "%d.%m.%Y"),
                   fiscalYears=fys,
                   fiscalYear=str(fiscal_year))
def make_sector_doc(sector_code):
    sector_brief_file = BytesIO()
    sector = qcodelists.get_code_by_id('mtef-sector', sector_code)
    sector_totals = qaggregates.aggregate('reporting-org',
                                          req_filters=[
                                              models.CodelistCode.codelist_code == 'mtef-sector',
                                              models.CodelistCode.code == sector_code
                                          ],
                                          req_finances_joins=[
                                              models.ActivityFinancesCodelistCode,
                                              models.CodelistCode
                                          ],
                                          req_forwardspends_joins=[
                                              models.ActivityCodelistCode,
                                              models.CodelistCode
                                          ]
                                          )
    current_fy = util.FY('current')
    filtered_current_fy = list(
        filter(lambda entry: entry.fiscal_year == current_fy.fy_fy(), sector_totals))

    donors = {}
    for item in filtered_current_fy:
        if item.code not in donors:
            donors[item.code] = {
                'code': item.code,
                'name': item.name,
                'disbursements': 0.00,
                'forwardspends': 0.00
            }
        if item.transaction_type == 'D':
            donors[item.code]['disbursements'] = round(
                item.total_value/1000000)
        if item.transaction_type == 'FS':
            donors[item.code]['forwardspends'] = round(
                item.total_value/1000000)

    ongoing_query = db.session.query(
        func.sum(models.ActivityFinances.transaction_value).label("total_value")
    ).join(models.Activity
           ).join(models.ActivityFinancesCodelistCode
                  ).join(models.CodelistCode
                         ).filter(
        models.ActivityFinances.transaction_type == 'D',
        models.Activity.activity_status == 2,
        models.CodelistCode.codelist_code == 'mtef-sector',
        models.CodelistCode.code == sector_code
    ).scalar()
    ongoing = round(ongoing_query/1000000)

    filtered_current_fy_disb = list(
        filter(lambda item: item.transaction_type == 'D', filtered_current_fy))
    current_fy_disb = round(
        sum(map(lambda item: item.total_value, filtered_current_fy_disb))/1000000)

    filtered_current_fy_fs = list(
        filter(lambda item: item.transaction_type == 'FS', filtered_current_fy))
    current_fy_fs = round(
        sum(map(lambda item: item.total_value, filtered_current_fy_fs))/1000000)

    filtered_cumulative_d = list(
        filter(lambda item: item.transaction_type == 'D', sector_totals))
    cumulative_d = round(
        sum(map(lambda item: item.total_value, filtered_cumulative_d))/1000000)

    document = docx.Document("projectdashboard/lib/docx/template.docx")
    document.add_heading('{} Sector Brief'.format(sector.name), 1)
    document.add_heading("General Information", 2)

    # Sector donors
    paragraph = document.add_paragraph()
    run = paragraph.add_run("Sector donors: ")
    font = run.font
    font.bold = True
    run = paragraph.add_run(
        f"Includes current fiscal year projected and actual disbursement information for donors operating in the sector for { current_fy.fy_fy() } ({ current_fy.date_format('start') } to { current_fy.date_format('end') })")
    font = run.font
    font.italic = True
    sector_donors = [(
        donor['name'],
        "USD {:,}m".format(donor['forwardspends']),
        "USD {:,}m".format(donor['disbursements'])
    ) for donor in donors.values()]
    if len(sector_donors) > 0:
        docx.rows_to_table(sector_donors, document, [
                       'Donor', 'Amount Projected', 'Amount Disbursed'])

    # Sector portfolio value
    paragraph = document.add_paragraph()
    paragraph = document.add_paragraph()
    run = paragraph.add_run("Sector portfolio value: ")
    font = run.font
    font.bold = True
    run = paragraph.add_run(
        "Includes cumulative financial information about the sector")
    font = run.font
    font.italic = True
    sector_portfolio = [(
        "",
        "USD {:,}m".format(ongoing),
        "",
        "",
        "USD {:,}m".format(current_fy_disb),
        "USD {:,}m".format(current_fy_fs),
        "USD {:,}m".format(cumulative_d))
    ]
    docx.rows_to_table(sector_portfolio, document, ['Total PAPD Financing Cost', 'Total value of all ongoing projects', 'GOL budget allocation',
                       'PAPD financing Gap', 'Current Fiscal year projection', 'Current fiscal year disbursement', 'Cumulative Disbursement from FY12/13'])

    # Sector thematic
    paragraph = document.add_paragraph()
    paragraph = document.add_paragraph()
    run = paragraph.add_run("Key Sector Thematic Areas (PAPD): ")
    font = run.font
    font.bold = True
    run = paragraph.add_run("Includes area of focus in the PAPD")
    font = run.font
    font.italic = True
    sector_thematic = [
        ("", ""),
        ("", ""),
        ("", ""),
    ]
    docx.rows_to_table(sector_thematic, document, ['Thematic area', 'Comment'])

    # Sector deliverables
    paragraph = document.add_paragraph()
    paragraph = document.add_paragraph()
    run = paragraph.add_run("Key Expected deliverables: ")
    font = run.font
    font.bold = True
    run = paragraph.add_run("Includes a summary of key expected deliverables ")
    font = run.font
    font.italic = True
    sector_deliverables = [
        ("", ""),
        ("", ""),
        ("", ""),
    ]
    docx.rows_to_table(sector_deliverables, document, [
                       'Key expected deliverable', 'Comment'])

    # Sector deliverables
    paragraph = document.add_paragraph()
    paragraph = document.add_paragraph()
    run = paragraph.add_run("Key Results Achieved: ")
    font = run.font
    font.bold = True
    run = paragraph.add_run("Includes a summary of key results achieved")
    font = run.font
    font.italic = True
    results_achieved = [
        ("", ""),
        ("", ""),
        ("", ""),
    ]
    docx.rows_to_table(results_achieved, document, [
                       'Results achieved', 'Comment'])

    # Sector thematic gap
    paragraph = document.add_paragraph()
    paragraph = document.add_paragraph()
    run = paragraph.add_run("Sector thematic gap: ")
    font = run.font
    font.bold = True
    run = paragraph.add_run(
        "Includes PAPD thematic areas still requiring funding")
    font = run.font
    font.italic = True
    thematic_gap = [
        ("", ""),
        ("", ""),
        ("", ""),
    ]
    docx.rows_to_table(thematic_gap, document, ['Thematic area', 'Comment'])

    # Issues and Challenges:
    paragraph = document.add_paragraph()
    paragraph = document.add_paragraph()
    run = paragraph.add_run("Issues and Challenges: ")
    font = run.font
    font.bold = True
    run = paragraph.add_run(
        "Includes a summary of key issues and challenges requiring action")
    font = run.font
    font.italic = True
    issues_challenges = [
        ("", ""),
        ("", ""),
        ("", ""),
    ]
    docx.rows_to_table(issues_challenges, document, [
                       'Issues/challenges', 'Status'])

    # Save
    document.save(sector_brief_file)
    return sector_brief_file
Beispiel #10
0
def available_fys():
    fy = util.FY("previous").fiscal_year.name
    return jsonify(fys=util.available_fys_as_dict(), current_fy=fy)