Skip to content

Commit

Permalink
Merge pull request #691 from dinukadesilva/fix-pe-4-response-time
Browse files Browse the repository at this point in the history
Fixes on PE-27, PE-4 and CE-201
  • Loading branch information
dinukadesilva authored Jul 15, 2020
2 parents d7dc0a1 + 06924c8 commit 9a0d890
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 108 deletions.
118 changes: 114 additions & 4 deletions results-tabulation-api/ext/ExtendedElection/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,122 @@ def get_area_map_for_tally_sheet(self, tally_sheet):

return self.get_area_map(area=area)

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

area_map_subquery = self.get_area_map_query().subquery()

return db.session.query(area_map_subquery).filter(
area_map_subquery.c.electionId.in_(self.election.get_this_and_below_election_ids())
)
if area is None:
return db.session.query(area_map_subquery).filter(
area_map_subquery.c.electionId.in_(self.election.get_this_and_below_election_ids())
)

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_by is None:
if area.areaType in area_and_vote_type_wise_filter_map:
filter_by = area_and_vote_type_wise_filter_map[area.areaType]
else:
filter_by = []

query_filter = filter_by

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

return area_map

def get_area_map_query(self):

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,47 +68,6 @@ class TallySheetModel(db.Model):
secondaryjoin="TallySheetModel.tallySheetId==TallySheetTallySheetModel.parentTallySheetId"
)

def get_tally_sheet_workflow_instance_actions(self):
tally_sheet_workflow_instance_actions = db.session.query(
WorkflowActionModel.workflowActionId,
WorkflowActionModel.actionName,
WorkflowActionModel.actionType,
WorkflowActionModel.fromStatus,
WorkflowActionModel.toStatus,
WorkflowInstance.Model.status
).filter(
WorkflowInstance.Model.workflowInstanceId == self.workflowInstanceId,
WorkflowActionModel.workflowId == WorkflowInstance.Model.workflowId
).order_by(
WorkflowActionModel.workflowActionId
).all()

processed_tally_sheet_workflow_instance_actions = []
for tally_sheet_workflow_instance_action in tally_sheet_workflow_instance_actions:
processed_tally_sheet_workflow_instance_actions.append({
"workflowActionId": tally_sheet_workflow_instance_action.workflowActionId,
"actionName": tally_sheet_workflow_instance_action.actionName,
"actionType": tally_sheet_workflow_instance_action.actionType,
"fromStatus": tally_sheet_workflow_instance_action.fromStatus,
"toStatus": tally_sheet_workflow_instance_action.toStatus,
"allowed": tally_sheet_workflow_instance_action.fromStatus == tally_sheet_workflow_instance_action.status,
"authorized": has_role_based_access(tally_sheet=self,
access_type=tally_sheet_workflow_instance_action.actionType)
})

return processed_tally_sheet_workflow_instance_actions

@hybrid_property
def workflowInstanceActions(self):
return self.get_tally_sheet_workflow_instance_actions()

@hybrid_property
def areaMapList(self):
extended_election = self.submission.election.get_extended_election()
area_map = extended_election.get_area_map_for_tally_sheet(tally_sheet=self)

return area_map

def add_parent(self, parentTallySheet):
parentTallySheet.add_child(self)

Expand Down Expand Up @@ -140,8 +99,6 @@ def set_latest_version(self, tallySheetVersion: TallySheetVersion):
else:
self.submission.set_latest_version(submissionVersion=tallySheetVersion.submissionVersion)

self.update_status_report()

@hybrid_property
def latestVersion(self):
return TallySheetVersion.Model.query.filter(
Expand Down Expand Up @@ -425,6 +382,21 @@ def _get_electoral_district_name(polling_division):
return electoral_district_name


def refactor_tally_sheet_response(tally_sheet):
workflow_instance = tally_sheet.workflowInstance
workflow_actions = tally_sheet.workflowInstance.workflow.actions
for workflow_action in workflow_actions:
setattr(workflow_action, "allowed", workflow_action.fromStatus == workflow_instance.status)
setattr(workflow_action, "authorized", has_role_based_access(tally_sheet=tally_sheet,
access_type=workflow_action.actionType))
setattr(tally_sheet.workflowInstance, "actions", workflow_actions)

setattr(tally_sheet, "areaId", tally_sheet.submission.areaId)
setattr(tally_sheet, "area", tally_sheet.submission.area)

return tally_sheet


def get_by_id(tallySheetId, tallySheetCode=None):
# Filter by authorized areas
user_access_area_ids: Set[int] = get_user_access_area_ids()
Expand All @@ -450,7 +422,7 @@ def get_by_id(tallySheetId, tallySheetCode=None):
code=MESSAGE_CODE_TALLY_SHEET_NOT_AUTHORIZED_TO_VIEW
)

return tally_sheet
return refactor_tally_sheet_response(tally_sheet)


def get_all(electionId=None, areaId=None, tallySheetCode=None, voteType=None):
Expand Down Expand Up @@ -484,6 +456,7 @@ def get_all(electionId=None, areaId=None, tallySheetCode=None, voteType=None):
authorized_tally_sheet_list = []
for tally_sheet in tally_sheet_list:
if has_role_based_access(tally_sheet=tally_sheet, access_type=WORKFLOW_ACTION_TYPE_VIEW):
refactor_tally_sheet_response(tally_sheet)
authorized_tally_sheet_list.append(tally_sheet)

return authorized_tally_sheet_list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class WorkflowInstanceModel(db.Model):
latestLogId = db.Column(db.Integer, db.ForeignKey("workflowInstanceLog.workflowInstanceLogId"), nullable=True)
proofId = db.Column(db.Integer, db.ForeignKey("proof.proofId"), nullable=True)

workflow = relationship("WorkflowModel", foreign_keys=[workflowId], lazy='subquery')
latestLog = relationship(WorkflowInstanceLog.Model, foreign_keys=[latestLogId])
proof = relationship(Proof.Model, foreign_keys=[proofId])

Expand Down
3 changes: 3 additions & 0 deletions results-tabulation-api/orm/entities/Workflow/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy import case
from sqlalchemy.orm import relationship

from app import db

Expand All @@ -12,6 +13,8 @@ class WorkflowModel(db.Model):
firstStatus = db.Column(db.String(100), nullable=False)
lastStatus = db.Column(db.String(100), nullable=False)

actions = relationship("WorkflowActionModel", lazy='subquery')

@classmethod
def create(cls, workflowName, statuses, actions, firstStatus, lastStatus):
workflow: WorkflowModel = cls(workflowName=workflowName, firstStatus=firstStatus, lastStatus=lastStatus)
Expand Down
20 changes: 9 additions & 11 deletions results-tabulation-api/schemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,12 +393,12 @@ class Meta:
"templateId",
"template",
"electionId",
# "areaId",
# "area",
"areaId",
"area",
# "areaMapList",
"latestVersion",
"metaDataList",
# "workflowInstance",
"workflowInstance",
"latestVersionId"
)

Expand All @@ -407,7 +407,7 @@ class Meta:
# to use for deserialization
sqla_session = db.session

template = ma.Nested("TemplateSchema", only=["templateId", "templateName", "isDerived"])
template = ma.Nested("TemplateSchema", only=["templateId", "templateName", "isDerived", "rows"])
area = ma.Nested(AreaSchema, only=["areaId", "areaName"])
versions = ma.Nested(SubmissionVersionSchema, only="submissionVersionId", many=True)
latestVersion = ma.Nested(TallySheetVersionSchema)
Expand All @@ -417,7 +417,7 @@ class Meta:
submissionProof = ma.Nested(Proof_Schema)
metaDataList = ma.Nested(MetaDataSchema, many=True)
areaMapList = ma.Nested('AreaMapSchema', many=True, partial=True)
workflowInstance = ma.Nested(WorkflowInstanceSchema, only=["workflowId", "statuses", "status"])
workflowInstance = ma.Nested(WorkflowInstanceSchema, only=["workflowId", "actions", "status"])


class TallySheetSchema(ma.ModelSchema):
Expand All @@ -428,14 +428,12 @@ class Meta:
"templateId",
"template",
"electionId",
# "areaId",
# "area",
"areaId",
"area",
# "areaMapList",
"metaDataList",
"workflowInstance",
"workflowInstanceActions",
"latestVersionId",
"submission"
"latestVersionId"
)

model = TallySheet.Model
Expand All @@ -454,7 +452,7 @@ class Meta:
submissionProof = ma.Nested(Proof_Schema)
metaDataList = ma.Nested(MetaDataSchema, many=True)
areaMapList = ma.Nested('AreaMapSchema', many=True, partial=True)
workflowInstance = ma.Nested(WorkflowInstanceSchema, only=["workflowId", "status"])
workflowInstance = ma.Nested(WorkflowInstanceSchema, only=["workflowId", "actions", "status"])
workflowInstanceActions = ma.Nested(StatusActionSchema, many=True)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ export default function TallySheetEdit_PE_27({history, queryString, election, ta
<TableCell align="center">Party Name</TableCell>
<TableCell align="center">Party Symbol</TableCell>
<TableCell align="center">Count in words</TableCell>
<TableCell align="right">Count in figures</TableCell>
<TableCell align="center">Count in figures</TableCell>
</TableRow>
</TableHead>
<TableBody>
Expand All @@ -270,7 +270,7 @@ export default function TallySheetEdit_PE_27({history, queryString, election, ta
}}
/>
</TableCell>
<TableCell align="right">
<TableCell align="center">
<TextField
required
variant="outlined"
Expand All @@ -293,7 +293,7 @@ export default function TallySheetEdit_PE_27({history, queryString, election, ta
<TableFooter>
<TableRow>
<TableCell align="right" colSpan={3}>Total valid vote count</TableCell>
<TableCell align="right">
<TableCell align="center">
<TextField
required
error={calculateTotalValidVoteCount() !== validVoteCountRow.numValue}
Expand All @@ -306,7 +306,7 @@ export default function TallySheetEdit_PE_27({history, queryString, election, ta
</TableRow>
<TableRow>
<TableCell align="right" colSpan={3}>Total rejected vote count</TableCell>
<TableCell align="right"><TextField
<TableCell align="center"><TextField
required
error={!isNumeric(rejectedVoteCountRow.numValue)}
helperText={!isNumeric(rejectedVoteCountRow.numValue) ? "Only numeric values are valid" : ''}
Expand All @@ -317,7 +317,7 @@ export default function TallySheetEdit_PE_27({history, queryString, election, ta
</TableRow>
<TableRow>
<TableCell align="right" colSpan={3}>Total vote count</TableCell>
<TableCell align="right">
<TableCell align="center">
<TextField
required
error={calculateTotalVoteCount() !== voteCountRow.numValue}
Expand Down
Loading

0 comments on commit 9a0d890

Please sign in to comment.