Skip to content

Commit

Permalink
Merge pull request #277 from umayangag/master
Browse files Browse the repository at this point in the history
PRE-34-CO view edit
  • Loading branch information
dinukadesilva authored Oct 31, 2019
2 parents 77eef15 + d063ede commit f60ec25
Show file tree
Hide file tree
Showing 12 changed files with 1,262 additions and 801 deletions.
47 changes: 47 additions & 0 deletions api/TallySheetVersionApi/TallySheetVersion_PRE_34_CO_Api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from app import db
from auth import authorize, EC_LEADERSHIP_ROLE
from auth.AuthConstants import DATA_EDITOR_ROLE
from exception import NotFoundException
from orm.entities.Submission import TallySheet
from orm.entities.SubmissionVersion import TallySheetVersion
from orm.enums import TallySheetCodeEnum
from schemas import TallySheetVersion_PRE_34_CO_Schema, TallySheetVersionSchema
from util import RequestBody


@authorize(required_roles=[DATA_EDITOR_ROLE, EC_LEADERSHIP_ROLE])
def get_by_id(tallySheetId, tallySheetVersionId):
tallySheet = TallySheet.get_by_id(tallySheetId=tallySheetId)
if tallySheet is None:
raise NotFoundException("Tally sheet not found. (tallySheetId=%d)" % tallySheetId)

result = TallySheetVersion.get_by_id(
tallySheetId=tallySheetId,
tallySheetVersionId=tallySheetVersionId
)

return TallySheetVersion_PRE_34_CO_Schema().dump(result).data


@authorize(required_roles=[DATA_EDITOR_ROLE])
def create(tallySheetId, body):
request_body = RequestBody(body)
tallySheet, tallySheetVersion = TallySheet.create_latest_version(
tallySheetId=tallySheetId,
tallySheetCode=TallySheetCodeEnum.PRE_34_CO
)
tallySheetVersion.set_complete() # TODO: valid before setting complete. Refer to PRE_34_CO
tally_sheet_content = request_body.get("content")
if tally_sheet_content is not None:
for row in tally_sheet_content:
party_count_body = RequestBody(row)
tallySheetVersion.add_row(
electionId=tallySheetVersion.submission.electionId,
candidateId=party_count_body.get("candidateId"),
preferenceCount=party_count_body.get("preferenceCount"),
preferenceNumber=party_count_body.get("preferenceNumber"),
)

db.session.commit()

return TallySheetVersionSchema().dump(tallySheetVersion).data
28 changes: 28 additions & 0 deletions migrations/versions/1c10a1181f81_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""empty message
Revision ID: 1c10a1181f81
Revises: f3d6ad1fdd31
Create Date: 2019-10-31 15:19:30.297761
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '1c10a1181f81'
down_revision = 'f3d6ad1fdd31'
branch_labels = None
depends_on = None


def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.add_column('election_candidate', sa.Column('qualifiedForPreferences', sa.Boolean(), nullable=False))
### end Alembic commands ###


def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_column('election_candidate', 'qualifiedForPreferences')
### end Alembic commands ###
40 changes: 40 additions & 0 deletions migrations/versions/f3d6ad1fdd31_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""empty message
Revision ID: f3d6ad1fdd31
Revises: 46e1b58e2e67
Create Date: 2019-10-31 14:26:47.708066
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'f3d6ad1fdd31'
down_revision = '46e1b58e2e67'
branch_labels = None
depends_on = None


def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('tallySheetVersionRow_PRE_34_Preference',
sa.Column('tallySheetVersionRowId', sa.Integer(), nullable=False),
sa.Column('tallySheetVersionId', sa.Integer(), nullable=False),
sa.Column('electionId', sa.Integer(), nullable=False),
sa.Column('candidateId', sa.Integer(), nullable=True),
sa.Column('preferenceNumber', sa.Integer(), nullable=False),
sa.Column('preferenceCount', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['candidateId'], ['candidate.candidateId'], ),
sa.ForeignKeyConstraint(['electionId'], ['election.electionId'], ),
sa.ForeignKeyConstraint(['tallySheetVersionId'], ['tallySheetVersion.tallySheetVersionId'], ),
sa.PrimaryKeyConstraint('tallySheetVersionRowId'),
sa.UniqueConstraint('tallySheetVersionId', 'preferenceNumber', 'candidateId', name='TallySheetVersionRow_RejectedVoteCount_Model')
)
### end Alembic commands ###


def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_table('tallySheetVersionRow_PRE_34_Preference')
### end Alembic commands ###
1 change: 1 addition & 0 deletions orm/entities/Election/ElectionCandidate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class ElectionCandidateModel(db.Model):
electionId = db.Column(db.Integer, db.ForeignKey("election.electionId"), nullable=False)
partyId = db.Column(db.Integer, db.ForeignKey(Party.Model.__table__.c.partyId), nullable=False)
candidateId = db.Column(db.Integer, db.ForeignKey(Candidate.Model.__table__.c.candidateId), nullable=False)
qualifiedForPreferences = db.Column(db.Boolean, default=False, nullable=False)

election = relationship("ElectionModel", foreign_keys=[electionId])
party = relationship(Party.Model, foreign_keys=[partyId])
Expand Down
6 changes: 6 additions & 0 deletions orm/entities/Election/election_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ def get_object(election, row, row_key, data_key=None):
TallySheet.create(
tallySheetCode=TallySheetCodeEnum.CE_201, electionId=election.electionId, areaId=obj.areaId
)
TallySheet.create(
tallySheetCode=TallySheetCodeEnum.PRE_34_CO, electionId=election.electionId, areaId=obj.areaId
)
elif election.voteType is VoteTypeEnum.Postal:
obj = CountingCentre.create(
cell, electionId=election.electionId,
Expand All @@ -202,6 +205,9 @@ def get_object(election, row, row_key, data_key=None):
TallySheet.create(
tallySheetCode=TallySheetCodeEnum.CE_201_PV, electionId=election.electionId, areaId=obj.areaId
)
TallySheet.create(
tallySheetCode=TallySheetCodeEnum.PRE_34_CO, electionId=election.electionId, areaId=obj.areaId
)

elif data_store_key == "Polling Station":
obj = PollingStation.create(
Expand Down
3 changes: 2 additions & 1 deletion orm/entities/Submission/TallySheet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ def create_empty_version(tallySheetId, tallySheetCode=None):
def create_version(tallySheetId, tallySheetCode=None):
tallySheet = get_by_id(tallySheetId=tallySheetId, tallySheetCode=tallySheetCode)
if tallySheet is None:
raise NotFoundException("Tally sheet not found. (tallySheetId=%d)" % tallySheetId)
raise NotFoundException(
"Tally sheet not found. (tallySheetId=%d, tallySheetCode=%s)" % (tallySheetId, tallySheetCode.name))

tallySheetVersion = tallySheet.create_version()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
from flask import render_template
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy import func, and_, or_
from app import db
from orm.entities import Area, Candidate, Party, Election
from orm.entities.Election import ElectionCandidate
from orm.entities.SubmissionVersion import TallySheetVersion
from orm.entities.TallySheetVersionRow import TallySheetVersionRow_PRE_34_preference
from util import to_comma_seperated_num, sqlalchemy_num_or_zero
from orm.enums import TallySheetCodeEnum, AreaTypeEnum, VoteTypeEnum


class TallySheetVersion_PRE_34_CO_Model(TallySheetVersion.Model):

def __init__(self, tallySheetId):
super(TallySheetVersion_PRE_34_CO_Model, self).__init__(
tallySheetId=tallySheetId
)

__mapper_args__ = {
'polymorphic_identity': TallySheetCodeEnum.PRE_34_CO
}

def add_row(self, preferenceNumber, preferenceCount, candidateId, electionId):
from orm.entities.TallySheetVersionRow import TallySheetVersionRow_PRE_34_preference

TallySheetVersionRow_PRE_34_preference.create(
tallySheetVersionId=self.tallySheetVersionId,
electionId=electionId,
preferenceNumber=preferenceNumber,
preferenceCount=preferenceCount,
candidateId=candidateId
)

@hybrid_property
def content(self):

return db.session.query(
ElectionCandidate.Model.candidateId,
Candidate.Model.candidateName,
Party.Model.partySymbol,
TallySheetVersionRow_PRE_34_preference.Model.preferenceNumber,
TallySheetVersionRow_PRE_34_preference.Model.preferenceCount,
TallySheetVersionRow_PRE_34_preference.Model.tallySheetVersionId,
TallySheetVersionRow_PRE_34_preference.Model.electionId
).join(
TallySheetVersionRow_PRE_34_preference.Model,
and_(
TallySheetVersionRow_PRE_34_preference.Model.candidateId == ElectionCandidate.Model.candidateId,
TallySheetVersionRow_PRE_34_preference.Model.tallySheetVersionId == self.tallySheetVersionId,
),
isouter=True
).join(
Candidate.Model,
Candidate.Model.candidateId == ElectionCandidate.Model.candidateId,
isouter=True
).join(
Party.Model,
Party.Model.partyId == ElectionCandidate.Model.partyId,
isouter=True
).filter(
ElectionCandidate.Model.electionId.in_(self.submission.election.mappedElectionIds),
ElectionCandidate.Model.qualifiedForPreferences == True
).all()

def html(self):
stamp = self.stamp

polling_divisions = Area.get_associated_areas(self.submission.area, AreaTypeEnum.PollingDivision)
polling_division_name = ""
if len(polling_divisions) > 0:
polling_division_name = polling_divisions[0].areaName

content = {
"election": {
"electionName": self.submission.election.get_official_name()
},
"stamp": {
"createdAt": stamp.createdAt,
"createdBy": stamp.createdBy,
"barcodeString": stamp.barcodeString
},
"title": "PRESIDENTIAL ELECTION ACT NO. 15 OF 1981",
"electoralDistrict": Area.get_associated_areas(
self.submission.area, AreaTypeEnum.ElectoralDistrict)[0].areaName,
"pollingDivision": polling_division_name,
"countingCentre": self.submission.area.areaName,
"pollingDistrictNos": ", ".join([
pollingDistrict.areaName for pollingDistrict in
Area.get_associated_areas(self.submission.area, AreaTypeEnum.PollingDistrict)
]),
"data": [
],
}

# for row_index in range(len(tallySheetContent)):
# row = tallySheetContent[row_index]
# if row.count is not None:
# content["data"].append([
# row_index + 1,
# row.candidateName,
# row.partySymbol,
# row.preferenceNumber,
# to_comma_seperated_num(row.count),
# ""
# ])
# else:
# content["data"].append([
# row_index + 1,
# row.candidateName,
# row.partySymbol,
# "",
# "",
# ""
# ])

html = render_template(
'PRE-34-CO.html',
content=content
)

return html


Model = TallySheetVersion_PRE_34_CO_Model
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import relationship

from app import db
from orm.entities import Area, Election, Candidate
from orm.entities.SubmissionVersion import TallySheetVersion


class TallySheetVersionRow_PRE_34_preference_Model(db.Model):
__tablename__ = 'tallySheetVersionRow_PRE_34_Preference'
tallySheetVersionRowId = db.Column(db.Integer, primary_key=True, autoincrement=True)
tallySheetVersionId = db.Column(db.Integer, db.ForeignKey(TallySheetVersion.Model.__table__.c.tallySheetVersionId),
nullable=False)
electionId = db.Column(db.Integer, db.ForeignKey(Election.Model.__table__.c.electionId), nullable=False)
candidateId = db.Column(db.Integer, db.ForeignKey(Candidate.Model.__table__.c.candidateId), nullable=True)
preferenceNumber = db.Column(db.Integer, nullable=False)
preferenceCount = db.Column(db.Integer, nullable=False)

candidate = relationship(Candidate.Model, foreign_keys=[candidateId])
election = relationship(Election.Model, foreign_keys=[electionId])

areaName = association_proxy("area", "areaName")

__table_args__ = (
db.UniqueConstraint('tallySheetVersionId', 'preferenceNumber', 'candidateId',
name='TallySheetVersionRow_RejectedVoteCount_Model'),
)

def __init__(self, electionId, tallySheetVersionId, preferenceNumber, preferenceCount, candidateId):
super(TallySheetVersionRow_PRE_34_preference_Model, self).__init__(
electionId=electionId,
tallySheetVersionId=tallySheetVersionId,
preferenceNumber=preferenceNumber,
preferenceCount=preferenceCount,
candidateId=candidateId
)
db.session.add(self)
db.session.flush()


Model = TallySheetVersionRow_PRE_34_preference_Model


def create(electionId, tallySheetVersionId, preferenceNumber, preferenceCount, candidateId):
result = Model(
electionId=electionId,
tallySheetVersionId=tallySheetVersionId,
preferenceNumber=preferenceNumber,
preferenceCount=preferenceCount,
candidateId=candidateId
)

return result
Loading

0 comments on commit f60ec25

Please sign in to comment.