Skip to content

Commit

Permalink
Adding an endpoint to get the election wise area-mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
dinukadesilva committed Jul 15, 2020
1 parent e872a8a commit 8afa819
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 117 deletions.
17 changes: 16 additions & 1 deletion results-tabulation-api/api/ElectionApi.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from exception.messages import MESSAGE_CODE_ELECTION_NOT_FOUND
from orm.entities.Election.election_helper import get_root_token
from orm.entities import Election
from schemas import ElectionSchema as Schema
from schemas import ElectionSchema as Schema, AreaMapSchema
from util import RequestBody, get_paginated_query


Expand Down Expand Up @@ -60,3 +60,18 @@ def create(body):
@authorize(required_roles=[ADMIN_ROLE])
def getRootToken(electionId):
return get_root_token(electionId=electionId)


@authorize(required_roles=ALL_ROLES)
def get_area_map(electionId=None):
election = Election.get_by_id(electionId=electionId)
if election is None:
raise NotFoundException(
message="Election not found (electionId=%d)" % electionId,
code=MESSAGE_CODE_ELECTION_NOT_FOUND
)

extended_election = election.get_extended_election()
area_map = extended_election.get_area_map()

return AreaMapSchema(many=True).dump(area_map).data
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ def get_area_map_query(self):
electoral_district.c.areaName.label("electoralDistrictName"),
counting_centre.c.areaId.label("countingCentreId"),
counting_centre.c.areaName.label("countingCentreName"),
Election.Model.voteType
Election.Model.voteType,
Election.Model.electionId
]

query_filter = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ def get_area_map_query(self):
electoral_district.c.areaName.label("electoralDistrictName"),
counting_centre.c.areaId.label("countingCentreId"),
counting_centre.c.areaName.label("countingCentreName"),
Election.Model.voteType
Election.Model.voteType,
Election.Model.electionId
]

query_filter = [
Expand Down
116 changes: 6 additions & 110 deletions results-tabulation-api/ext/ExtendedElection/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,117 +60,12 @@ def get_area_map_for_tally_sheet(self, tally_sheet):

return self.get_area_map(area=area)

def get_area_map(self, area, group_by=None, filter=None):
from orm.enums import AreaTypeEnum

def get_area_map(self):
area_map_subquery = self.get_area_map_query().subquery()

column_name_list = [
"pollingStationId", "pollingStationName",
"pollingDistrictId", "pollingDistrictName",
"countingCentreId", "countingCentreName",
"pollingDivisionId", "pollingDivisionName",
"electoralDistrictId", "electoralDistrictName",
"countryId", "countryName"
]
column_name_to_column_map = {
"pollingStationId": area_map_subquery.c.pollingStationId,
"pollingStationName": area_map_subquery.c.pollingStationName,
"pollingDistrictId": area_map_subquery.c.pollingDistrictId,
"pollingDistrictName": area_map_subquery.c.pollingDistrictName,
"countingCentreId": area_map_subquery.c.countingCentreId,
"countingCentreName": area_map_subquery.c.countingCentreName,
"pollingDivisionId": area_map_subquery.c.pollingDivisionId,
"pollingDivisionName": area_map_subquery.c.pollingDivisionName,
"electoralDistrictId": area_map_subquery.c.electoralDistrictId,
"electoralDistrictName": area_map_subquery.c.electoralDistrictName,
"countryId": area_map_subquery.c.countryId,
"countryName": area_map_subquery.c.countryName
}
query_args = []
query_filter = []
query_group_by = []
area_and_vote_type_wise_group_by_map = {
AreaTypeEnum.CountingCentre: [
"countingCentreId",
"countingCentreName",
"pollingDivisionId",
"pollingDivisionName",
"electoralDistrictId",
"electoralDistrictName",
"countryId",
"countryName"
],
AreaTypeEnum.PollingStation: [
"pollingDistrictId",
"pollingDistrictName",
"pollingStationId",
"pollingStationName",
"countingCentreId",
"countingCentreName",
"pollingDivisionId",
"pollingDivisionName",
"electoralDistrictId",
"electoralDistrictName",
"countryId",
"countryName"
],
AreaTypeEnum.PollingDivision: [
"pollingDivisionId",
"pollingDivisionName",
"electoralDistrictId",
"electoralDistrictName",
"countryId",
"countryName"
],
AreaTypeEnum.ElectoralDistrict: [
"electoralDistrictId",
"electoralDistrictName",
"countryId",
"countryName"
],
AreaTypeEnum.Country: [
"countryId",
"countryName"
]
}

area_and_vote_type_wise_filter_map = {
AreaTypeEnum.PollingStation: [area_map_subquery.c.pollingStationId == area.areaId],
AreaTypeEnum.PollingDistrict: [area_map_subquery.c.pollingDistrictId == area.areaId],
AreaTypeEnum.CountingCentre: [area_map_subquery.c.countingCentreId == area.areaId],
AreaTypeEnum.PollingDivision: [area_map_subquery.c.pollingDivisionId == area.areaId],
AreaTypeEnum.ElectoralDistrict: [area_map_subquery.c.electoralDistrictId == area.areaId],
AreaTypeEnum.Country: [area_map_subquery.c.countryId == area.areaId]
}

if group_by is None:
if area.areaType in area_and_vote_type_wise_group_by_map:
group_by = area_and_vote_type_wise_group_by_map[area.areaType]
else:
group_by = []

for column_name in column_name_list:
column = column_name_to_column_map[column_name]
if column_name in group_by:
query_group_by.append(column)

# Append the column to query.
query_args.append(column)
else:
query_args.append(bindparam(column_name, None))

if filter is None:
if area.areaType in area_and_vote_type_wise_filter_map:
filter = area_and_vote_type_wise_filter_map[area.areaType]
else:
filter = []

query_filter = filter

area_map = db.session.query(*query_args).filter(*query_filter).group_by(*query_group_by).all()

return area_map
return db.session.query(area_map_subquery).filter(
area_map_subquery.c.electionId.in_(self.election.get_this_and_below_election_ids())
)

def get_area_map_query(self):

Expand Down Expand Up @@ -216,7 +111,8 @@ def get_area_map_query(self):
polling_station.c.areaName.label("pollingStationName"),
counting_centre.c.areaId.label("countingCentreId"),
counting_centre.c.areaName.label("countingCentreName"),
Election.Model.voteType
Election.Model.voteType,
Election.Model.electionId
).filter(
country__electoral_district.parentAreaId == country.c.areaId,
country__electoral_district.childAreaId == electoral_district.c.areaId,
Expand Down
2 changes: 1 addition & 1 deletion results-tabulation-api/schemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ class Meta:
"electionId",
# "areaId",
# "area",
"areaMapList",
# "areaMapList",
"latestVersion",
"metaDataList",
# "workflowInstance",
Expand Down
47 changes: 47 additions & 0 deletions results-tabulation-api/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,53 @@ paths:
schema:
$ref: '#/components/schemas/ApiResponse'

/election/{electionId}/area-map:
get:
tags:
- Election
summary: Get Area Map
operationId: api.ElectionApi.get_area_map
parameters:
- name: electionId
in: path
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Successful operation.
content:
application/json:
schema:
type: array
items:
type: object
'400':
description: Bad request.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'401':
description: Unauthorized.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'404':
description: Resource was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'500':
description: Unexpected error.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'

/election:
get:
tags:
Expand Down
29 changes: 26 additions & 3 deletions results-tabulation-ui/src/services/election.provider.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useState} from "react";
import {
ENDPOINT_PATH_ELECTION_AREA_MAP_BY_ID,
ENDPOINT_PATH_ELECTIONS,
ENDPOINT_PATH_ELECTIONS_BY_ID,
request
Expand All @@ -17,8 +18,13 @@ export function ElectionProvider(props) {

const saveElectionToState = (election) => {
const {electionId, metaDataList = [], parties} = election;
election.metaDataMap = getMetaDataMap(metaDataList);
election.partyMap = getPartyMap(parties);
if (!election.metaDataMap) {
election.metaDataMap = getMetaDataMap(metaDataList);
}

if (!election.partyMap) {
election.partyMap = getPartyMap(parties);
}

// To avoid duplicated election fetches while state update wait
state.electionMap[electionId] = {...election};
Expand Down Expand Up @@ -96,12 +102,29 @@ export function ElectionProvider(props) {
return election;
};


const getElectionAreaMap = async (electionId) => {
let election = await getElectionById(electionId);

if (!election.electionAreaMap) {
const electionAreaMap = await request({
url: ENDPOINT_PATH_ELECTION_AREA_MAP_BY_ID(electionId),
method: 'get', // default,
});

saveElectionToState(Object.assign(election, {electionAreaMap}));
}

return election.electionAreaMap;
};

return <ElectionContext.Provider
value={{
getElectionById: getElectionById,
getElections: getElections,
getSubElections: getSubElections,
getParentElection: getParentElection
getParentElection: getParentElection,
getElectionAreaMap: getElectionAreaMap
}}
>
{props.children}
Expand Down
1 change: 1 addition & 0 deletions results-tabulation-ui/src/services/tabulation-api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {getAccessToken} from "../../auth";

export const ENDPOINT_PATH_ELECTIONS = () => "/election";
export const ENDPOINT_PATH_ELECTIONS_BY_ID = (electionId) => `/election/${electionId}`;
export const ENDPOINT_PATH_ELECTION_AREA_MAP_BY_ID = (electionId) => `/election/${electionId}/area-map`;
export const ENDPOINT_PATH_AREAS = () => "/area";
export const ENDPOINT_PATH_AREAS_BY_ID = (areaId) => `/area/${areaId}`;
export const ENDPOINT_PATH_TALLY_SHEETS = () => "/tally-sheet";
Expand Down
1 change: 1 addition & 0 deletions results-tabulation-ui/src/services/tally-sheet.provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export function TallySheetProvider(props) {
tallySheet.election = await electionContext.getElectionById(tallySheet.electionId);
tallySheet.workflowInstance.actions = tallySheet.workflowInstanceActions;
tallySheet.area = tallySheet.submission.area;
tallySheet.areaMapList = await electionContext.getElectionAreaMap(tallySheet.electionId);

// TODO fetch actions and area maps

Expand Down

0 comments on commit 8afa819

Please sign in to comment.