MetaPhase-Consulting/State-TalentMAP-API

View on GitHub
talentmap_api/fsbid/services/agenda_employees.py

Summary

Maintainability
A
1 hr
Test Coverage
F
20%
import logging
import csv
from datetime import datetime
from urllib.parse import urlencode, quote
from functools import partial
from copy import deepcopy


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

import jwt
import maya
import pydash

from talentmap_api.fsbid.services import common as services


API_ROOT = settings.WS_ROOT_API_URL

logger = logging.getLogger(__name__)


def get_agenda_employees(query, jwt_token=None, host=None):
    '''
    Get employees
    '''
    from talentmap_api.fsbid.services.cdo import cdo
    try:
        cdos = list(cdo(jwt_token))
    except:
        cdos = []

    args = {
        "uri": "v1/tm-persons",
        "query": query,
        "query_mapping_function": convert_agenda_employees_query,
        "jwt_token": jwt_token,
        "mapping_function": partial(fsbid_agenda_employee_to_talentmap_agenda_employee, cdos=cdos),
        "count_function": get_agenda_employees_count,
        "base_url": '',
        "host": host,
        "use_post": False,
    }

    agenda_employees = services.send_get_request(
        **args
    )

    return agenda_employees

def get_agenda_employees_count(query, jwt_token, host=None, use_post=False):
    '''
    Get total number of employees for agenda search
    '''
    args = {
        "uri": "v1/tm-persons",
        "query": query,
        "query_mapping_function": convert_agenda_employees_query,
        "jwt_token": jwt_token,
        "host": host,
        "use_post": False,
        "is_template": True,
    }
    return services.send_count_request(**args)


def get_agenda_employees_csv(query, jwt_token, rl_cd, host=None):
    from talentmap_api.fsbid.services.common import send_get_csv_request, mapBool
    from talentmap_api.fsbid.services.cdo import cdo
    ad_id = jwt.decode(jwt_token, verify=False).get('unique_name')
    try:
        cdos = list(cdo(jwt_token))
    except:
        cdos = []
    csvQuery = deepcopy(query)
    csvQuery['page'] = 1
    csvQuery['limit'] = 500
    args = {
        "uri": "v1/tm-persons",
        "query": csvQuery,
        "query_mapping_function": convert_agenda_employees_query,
        "jwt_token": jwt_token,
        "mapping_function": partial(fsbid_agenda_employee_to_talentmap_agenda_employee, cdos=cdos),
        "base_url": API_ROOT,
        "host": host,
        "use_post": False,
    }

    data = send_get_csv_request(**args)

    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = f"attachment; filename=agenda_employees_{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"Employee ID"),
        smart_str(u"CDO"),
        smart_str(u"Current Organization"),
        smart_str(u"TED"),
        smart_str(u"Has Handshake"),
        smart_str(u"Handshake Organization"),
        smart_str(u"Panel Meeting Date"),
        smart_str(u"Agenda Status"),
    ])

    for record in data:
        fallback = 'None listed'
        try:
            ted = smart_str(maya.parse(record["currentAssignment"]["TED"]).datetime().strftime('%m/%d/%Y'))
        except:
            ted = fallback
        try:
            panelMeetingDate = smart_str(maya.parse(record["agenda"]["panelDate"]).datetime().strftime('%m/%d/%Y'))
        except:
            panelMeetingDate = fallback

        hasHandshake = True if pydash.get(record, 'hsAssignment.orgDescription') else False

        writer.writerow([
            smart_str(pydash.get(record, 'person.fullName')),
            smart_str("=\"%s\"" % pydash.get(record, "person.employeeID")),
            smart_str(pydash.get(record, 'person.cdo.name') or fallback),
            smart_str(pydash.get(record, 'currentAssignment.orgDescription') or fallback),
            smart_str(ted),
            smart_str(mapBool[hasHandshake]),
            smart_str(pydash.get(record, 'hsAssignment.orgDescription') or fallback),
            smart_str(panelMeetingDate),
            smart_str(pydash.get(record, 'agenda.status') or fallback),
        ])
    return response


def convert_agenda_employees_query(query):
    '''
    Convert TalentMAP filters into FSBid filters
    '''

    tedStart = query.get("ted-start")
    tedEnd = query.get("ted-end")

    firstName = query.get("firstName").upper() if query.get("firstName") else None
    lastName = query.get("lastName").upper() if query.get("lastName") else None
    empID = query.get("empID").upper() if query.get("empID") else None

    activeCodes = "S,L,A,P,U" if not query.get("isInactiveSelected") else None

    filters = [
        {"col": "tmpercurrentbureaucode", "com": "IN", "val": query.get("current-bureaus") or None},
        {"col": "tmperhsbureaucode", "com": "IN", "val": query.get("handshake-bureaus") or None},
        {"col": "tmpercurrentorgcode", "com": "IN", "val": query.get("current-organizations") or None},
        {"col": "tmperhsorgcode", "com": "IN", "val": query.get("handshake-organizations") or None},
        {"col": "tmpercdoid", "com": "IN", "val": query.get("cdos") or None},
        {"col": "tmperperscode", "com": "IN", "val": activeCodes},
        {"col": "tmperperdetseqnum", "com": "EQ", "val": query.get("perdet") or None},
        {"col": "tmperperfirstname", "com": "CONTAINS", "val": firstName},
        {"col": "tmperperlastname", "com": "CONTAINS", "val": lastName},
        {"col": "tmperpertexternalid", "com": "EQ", "val": empID}
    ]

    if query.get("handshake"):
        hsObj = {"col": "tmperhsind", "com": "IN"}
        hs = query.get("handshake") or None
        if hs == 'Y':
            hsObj['val'] = 'HS'
            filters.append(hsObj)
        elif hs == 'N':
            hsObj['com'] = 'EQ'
            hsObj['val'] = 'null'
            filters.append(hsObj)

    try:
        if tedStart and tedEnd:
            startVal = maya.parse(tedStart).datetime().strftime("%Y-%m-%d")
            endVal = maya.parse(tedEnd).datetime().strftime("%Y-%m-%d")
            filters.append({"col": "tmpercurrentted", "com": "GTEQ", "val": startVal, "isDate": True})
            filters.append({"col": "tmpercurrentted", "com": "LTEQ", "val": endVal, "isDate": True})
    except:
        logger.info(f"Invalid date {tedStart} or {tedEnd} could not be parsed.")

    filters = pydash.filter_(filters, lambda o: o["val"] is not None)

    filters = services.convert_to_fsbid_ql(filters)

    values = {
        # Pagination
        "rp.pageNum": int(query.get("page", 1)),
        "rp.pageRows": int(query.get("limit", 50)),
        "rp.orderBy": services.sorting_values(query.get("ordering", "agenda_employee_fullname")),
        "rp.filter": filters,
    }
    if query.get("getCount") == 'true':
        values["rp.pageNum"] = 0
        values["rp.pageRows"] = 0
        values["rp.columns"] = "ROWCOUNT"

    valuesToReturn = pydash.omit_by(values, lambda o: o is None or o == [])
    return urlencode(valuesToReturn, doseq=True, quote_via=quote)

def fsbid_agenda_employee_to_talentmap_agenda_employee(data, cdos=[]):
    '''
    Maps FSBid response to expected TalentMAP response
    '''
    firstN = data.get('perpiifirstname', '')
    lastN = data.get('perpiilastname', '')
    initials = f"{firstN[0] if firstN else ''}{lastN[0] if lastN else ''}"
    suffix = data.get('perpiisuffixname') or ''
    hasSuffix = len(suffix.strip()) > 0
    fullName = data.get("perpiifullname", "")
    if pydash.ends_with(fullName, "NMN"):
        fullName = fullName.rstrip(" NMN")
    if pydash.ends_with(fullName, "Nmn"):
        fullName = fullName.rstrip(" Nmn")
    cdo = None
    if pydash.get(data, 'cdo[0].echruid'):
        hru_id = pydash.get(data, 'cdo[0].echruid')
        cdoObj = pydash.find(cdos, lambda x: pydash.get(x, 'id') == hru_id)
        cdo = cdoObj
    return {
        "person": {
            "fullName": fullName + f"{', '+suffix if hasSuffix else ''} ",
            "perdet": data.get("perdetseqnum", ""),
            "employeeID": data.get("pertexternalid", ""),
            "initials": initials,
            "cdo": cdo,
        },
        "currentAssignment": {
            "TED": pydash.get(data, "currentAssignment[0].asgdetdteddate") or None,
            "orgDescription": pydash.get(data, "currentAssignment[0].position[0].posorgshortdesc") or None,
            "locationCity": pydash.get(data, "currentAssignment[0].position[0].location[0].loccity") or None,
            "locationCountry": pydash.get(data, "currentAssignment[0].position[0].location[0].loccountry") or None,
        },
        "hsAssignment": {
            "orgDescription": pydash.get(data, "handshake[0].posorgshortdesc") or None,
            "hsLocationCity": pydash.get(data, "handshake[0].position[0].location[0].loccity") or None,
            "hsLocationCountry": pydash.get(data, "handshake[0].position[0].location[0].loccountry") or None,
        },
        "agenda": {
            "panelDate": pydash.get(data, "latestAgendaItem[0].panels[0].pmddttm") or None,
            "status": pydash.get(data, "latestAgendaItem[0].aisdesctext") or None,
            "pmSeqNum": pydash.get(data, "latestAgendaItem[0].panels[0].pmseqnum") or None,
            "agendaID": pydash.get(data, "latestAgendaItem[0].aiseqnum") or None,
        }
    }


@staticmethod
def fsbid_person_current_organization_to_talentmap(data):
    return {
        "code": data.get("tmpercurrentorgcode", None),
        "name": data.get("tmpercurrentorgdesc", None),
    }


@staticmethod
def fsbid_person_handshake_organization_to_talentmap(data):
    return {
        "code": data.get("tmperhsorgcode", None),
        "name": data.get("tmperhsorgdesc", None),
    }


@staticmethod
def fsbid_person_current_bureau_to_talentmap(data):
    return {
        "code": data.get("tmpercurrentbureaucode", None),
        "name": data.get("tmpercurrentbureaudesc", None),
    }


@staticmethod
def fsbid_person_handshake_bureau_to_talentmap(data):
    return {
        "code": data.get("tmperhsbureaucode", None),
        "name": data.get("tmperhsbureaudesc", None),
    }