MetaPhase-Consulting/State-TalentMAP-API

View on GitHub
talentmap_api/cdo/services/available_bidders.py

Summary

Maintainability
B
6 hrs
Test Coverage
F
20%
import logging
import csv
import maya
import pydash
from copy import deepcopy

from django.conf import settings
from django.http import HttpResponse
from datetime import datetime
from django.utils.encoding import smart_str

import talentmap_api.bureau.services.available_bidders as bureau_services
import talentmap_api.fsbid.services.client as client_services

from talentmap_api.common.common_helpers import ensure_date, formatCSV

from talentmap_api.common.common_helpers import formatCSV
from talentmap_api.fsbid.services.common import mapBool

logger = logging.getLogger(__name__)


def get_available_bidders_stats(data):
    '''
    Returns all Available Bidders statistics
    '''
    stats = {
        'Bureau': {},
        'CDO': {},
        'Grade': {},
        'OC Bureau': {},
        'Post': {},
        'Skill': {},
        'Status': {},
    }

    stats_sum = {
        'Bureau': 0,
        'CDO': 0,
        'Grade': 0,
        'OC Bureau': 0,
        'Post': 0,
        'Skill': 0,
        'Status': 0,
    }

    config = [
        { 'key': 'current_assignment.position.bureau_code', 'statsKey': 'Bureau' },
        { 'key': 'cdo.full_name', 'statsKey': 'CDO' },
        { 'key': 'grade', 'statsKey': 'Grade' },
        { 'key': 'available_bidder_details.oc_bureau', 'statsKey': 'OC Bureau' },
        { 'key': 'pos_location', 'statsKey': 'Post' },
        { 'key': 'skills', 'statsKey': 'Skill' },
        { 'key': 'available_bidder_details.status', 'statsKey': 'Status' },
    ]

    none_listed = {'name': 'None listed', 'value': 0}

    if data:
        # get stats for various fields
        for bidder in pydash.get(data, 'results'):
            def map_object(stat):
                key = pydash.get(bidder, stat['key'])
                stats_key = stats[stat['statsKey']]
                if stat['key'] == 'skills':
                    skill = list(deepcopy(filter(None, bidder[stat['key']])))
                    key = skill[0]['code']
                    if key not in stats['Skill']:
                        stats_key[key] = deepcopy(none_listed) if key == None else {'name': f"{skill[0]['description']}", 'value': 0}
                else:
                    if key not in stats[stat['statsKey']]:
                        stats_key[key] = deepcopy(none_listed) if key == None else {'name': f"{key}", 'value': 0}

                stats_key[key]['value'] += 1
                stats_sum[stat['statsKey']] += 1

            pydash.for_each(config, map_object)

    # adding percentage & creating final data structure to pass to FE
    bidders_stats = {}
    for stat in stats:
        stat_sum = stats_sum[stat]
        bidders_stats[stat] = []
        for s in stats[stat]:
            stat_value = stats[stat][s]['value']
            bidders_stats[stat].append({**stats[stat][s], 'percent': "{:.0%}".format(stat_value / stat_sum)})

    # partition is used to handle the edge case when
    # len(bidders_stats['Post']) > 18 and all the post only have a value of 1
    # 18 was chosen due to UI Columns
    if len(bidders_stats['Post']) > 18:
        post_partition = pydash.partition(bidders_stats['Post'], lambda post: post['value'] > 1)
        take_from_pp = 18 - len(post_partition[0])
        post_partition[0].extend(post_partition[1][:take_from_pp])
        bidders_stats['Post'] = post_partition[0]
    
    bidders_stats['Grade'] = sorted(bidders_stats['Grade'], key = lambda grade: grade['name'])
    bidders_stats['Skill'] = sorted(bidders_stats['Skill'], key = lambda skill: skill['name'])
    bidders_stats['Sum'] = stats_sum

    return {
        "stats": bidders_stats,
    }


def get_available_bidders_csv(request):
    '''
    Returns csv format of Available Bidders list
    '''
    data = client_services.get_available_bidders(request.META['HTTP_JWT'], True, request.query_params, f"{request.scheme}://{request.get_host()}")
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = f"attachment; filename=Available_Bidders_{datetime.now().strftime('%Y_%m_%d_%H%M%S')}.csv"

    writer = csv.writer(response, csv.excel)
    response.write(u'\ufeff'.encode('utf8'))

    # write the headers
    writer.writerow([
        smart_str(u"Name"),
        smart_str(u"Status"),
        smart_str(u"OC Bureau"),
        smart_str(u"OC Reason"),
        smart_str(u"Step Letter One"),
        smart_str(u"Step Letter Two"),
        smart_str(u"Skills"),
        smart_str(u"Grade"),
        smart_str(u"Languages"),
        smart_str(u"TED"),
        smart_str(u"Organization"),
        smart_str(u"City"),
        smart_str(u"State"),
        smart_str(u"Country"),
        smart_str(u"CDO Name"),
        smart_str(u"CDO Email"),
        smart_str(u"Updated"),
        smart_str(u"Notes"),
        smart_str(u"Shared with Bureau"),
    ])
    fields_info = {
        "name": None,
        "status": {"path": 'available_bidder_details.status', },
        "step_letter_one": {"path": 'available_bidder_details.step_letter_one', },
        "step_letter_two": {"path": 'available_bidder_details.step_letter_two', },
        "skills": {"default": "No Skills listed", "description_and_code": True},
        "grade": None,
        "ted": {"path": 'current_assignment.end_date', },
        "oc_bureau": {"path": 'available_bidder_details.oc_bureau', },
        "oc_reason": {"path": 'available_bidder_details.oc_reason', },
        "org": {"path": 'current_assignment.position.organization', },
        "city": {"path": 'current_assignment.position.post.location.city', },
        "state": {"path": 'current_assignment.position.post.location.state', },
        "country": {"path": 'current_assignment.position.post.location.country', },
        "updated_on": {"path": 'available_bidder_details.update_date', },
        "notes": {"path": 'available_bidder_details.comments', },
        "is_shared": {"path": 'available_bidder_details.is_shared', },
        "cdo_email": {"path": 'cdo.email', },
    }

    for record in data["results"]:
        languages = f'' if pydash.get(record, "languages") else "None listed"
        if languages is not "None listed":
            for language in record["languages"]:
                languages += f'{language["custom_description"]}, '
        languages = languages.rstrip(', ')

        cdo_name = f'{pydash.get(record, "cdo.last_name")}, {pydash.get(record, "cdo.first_name")}'

        fields = formatCSV(record, fields_info)

        # Removing time zone text to allow Maya to parse
        update_date, x, y = fields["updated_on"].partition('(')
        update_date = maya.parse(update_date).datetime().strftime('%m/%d/%Y')

        try:
            ted = maya.parse(fields["ted"]).datetime().strftime('%m/%d/%Y')
        except:
            ted = 'None listed'
        try:
            step_letter_one = maya.parse(fields["step_letter_one"]).datetime().strftime('%m/%d/%Y')
        except:
            step_letter_one = 'None listed'
        try:
            step_letter_two = maya.parse(fields["step_letter_two"]).datetime().strftime('%m/%d/%Y')
        except:
            step_letter_two = 'None listed'
        writer.writerow([
            fields["name"],
            fields["status"],
            fields["oc_bureau"],
            fields["oc_reason"],
            step_letter_one,
            step_letter_two,
            fields["skills"],
            smart_str("=\"%s\"" % fields["grade"]),
            languages,
            ted,
            fields["org"],
            fields["city"],
            fields["state"],
            fields["country"],
            cdo_name,
            fields["cdo_email"],
            update_date,
            fields["notes"],
            mapBool[fields["is_shared"]],
        ])

    return response