Skip to content

Commit

Permalink
Election support fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnMwashuma committed Nov 24, 2024
1 parent 5f926f6 commit 1196aa7
Show file tree
Hide file tree
Showing 14 changed files with 1,085 additions and 189 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from django.core.management.base import BaseCommand
import csv
import pathlib
from django.utils import timezone
from tally_ho.apps.tally.models.result_form import ResultForm
from tally_ho.libs.models.enums.entry_version import EntryVersion
from tally_ho.libs.models.enums.form_state import FormState
from django.utils.translation import gettext_lazy

def generate_csv():
# Retrieve the form state using the provided enum number
form_state = FormState.QUALITY_CONTROL

# Filter result forms by form state
result_forms = ResultForm.objects.filter(
form_state=form_state, tally__id=1)

# Generate CSV file path with timestamp
timestamp = timezone.now().strftime('%Y%m%d_%H%M%S')
csv_filename = f'result_forms_{form_state.name}_{timestamp}.csv'
csv_filepath = pathlib.Path(csv_filename)

# Define the CSV column headers
headers = [
'barcode',
'center',
'station',
'ballot',
'race',
'triggers',
'user',
'date',
'audit',
'sub_name',
]

# Write the filtered result forms to the CSV file
with open(csv_filepath, mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(headers)

for result_form in result_forms:
barcode = result_form.barcode
center = result_form.center.code,
station = result_form.station_number
ballot = result_form.ballot.number,
race = result_form.ballot.electrol_race.ballot_name
user = result_form.user.username
modified_date = result_form.modified_date
audit_resolution = ""
triggers = ""
sub_name = result_form.center.sub_constituency.name

if (result_form.form_state == FormState.ARCHIVED) &\
(result_form.qualitycontrol is not None):
user = result_form.qualitycontrol.user.username
modified_date =\
result_form.qualitycontrol.modified_date_formatted

if (result_form.form_state == FormState.QUALITY_CONTROL) &\
(result_form.qualitycontrol is not None):
user = result_form.qualitycontrol.user.username
modified_date =\
result_form.qualitycontrol.modified_date_formatted

if (result_form.form_state == FormState.AUDIT) &\
(result_form.has_recon is True) &\
(result_form.audit is None):
recon_qs = result_form.reconciliationform_set.filter(
active=True, entry_version=EntryVersion.FINAL
)
if len(recon_qs):
user = recon_qs[0].user.username

if (result_form.form_state == FormState.AUDIT) &\
(result_form.has_recon is True) &\
(result_form.audit is not None):
audit_resolution =\
result_form.audit.resolution_recommendation_name()
quarantine_checks =\
[q.name for q in result_form.audit.quarantine_checks.all()]
if len(quarantine_checks):
triggers = " , ".join(quarantine_checks)
user = result_form.audit.user.username
modified_date = result_form.audit.modified_date_formatted

# Write the data row
writer.writerow([
barcode,
center[0],
station,
ballot[0],
race,
triggers,
user,
modified_date,
audit_resolution,
sub_name,
])

print(f"CSV file has been created: {csv_filepath}")


class Command(BaseCommand):
help = gettext_lazy("create result_form csv by form_state.")

def handle(self, *args, **kwargs):
self.create_result_form_csv_by_form_state()

def create_result_form_csv_by_form_state(self):
# Generate CSV based on the form state enum number
generate_csv()
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import csv
import pathlib

from django.core.management.base import BaseCommand
from django.utils.translation import gettext_lazy
from django.utils import timezone
from django.db.models import (
F, IntegerField, Subquery, OuterRef, Sum, Case, When, Value as V, CharField
)
from django.db.models.functions import Coalesce

from tally_ho.apps.tally.models.result import Result
from tally_ho.apps.tally.models.result_form import ResultForm
from tally_ho.apps.tally.models.station import Station
from tally_ho.libs.models.enums.entry_version import EntryVersion
from tally_ho.libs.models.enums.form_state import FormState

def generate_csv():
tally_id = 1
station_gender_query =\
Subquery(
Station.objects.filter(
tally__id=tally_id,
center__code=OuterRef(
'center__code'),
station_number=OuterRef(
'station_number'))
.values('gender')[:1],
output_field=IntegerField())
station_registrants_query =\
Subquery(
Station.objects.filter(
tally__id=tally_id,
center__code=OuterRef(
'center__code'),
station_number=OuterRef(
'station_number'))
.values('registrants')[:1],
output_field=IntegerField())

turnout_data = ResultForm.objects.filter(
tally__id=tally_id,
form_state=FormState.ARCHIVED,
).annotate(
station_gender_code=station_gender_query,
station_registrants=station_registrants_query,
station_gender=Case(
When(station_gender_code=0,
then=V('Man')),
default=V('Woman'),
output_field=CharField()),
municipality_name=F('center__sub_constituency__name'),
municipality_code=F('center__sub_constituency__code'),
sub_race_type=F('ballot__electrol_race__ballot_name')
).values(
'municipality_name',
'municipality_code',
'station_gender_code',
'station_gender',
'sub_race_type'
).annotate(
total_registrants=Sum('station_registrants')
# ).filter(municipality_code=102)
)

# Generate CSV file path with timestamp
timestamp = timezone.now().strftime('%Y%m%d_%H%M%S')
csv_filename = f'turnout_report_by_mun_by_race_by_gender_{timestamp}.csv'
csv_filepath = pathlib.Path(csv_filename)

# Define the CSV column headers
headers = [
'municipality_name',
'municipality_code',
'sub_race',
'human',
'voters',
'registrants',
'turnout',
]

with open(csv_filepath, mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(headers)

for data in turnout_data:
result_station_gender_query =\
Subquery(
Station.objects.filter(
tally__id=tally_id,
center__code=OuterRef(
'result_form__center__code'),
station_number=OuterRef(
'result_form__station_number'))
.values('gender')[:1],
output_field=IntegerField())
result_station_registrants_query =\
Subquery(
Station.objects.filter(
tally__id=tally_id,
center__code=OuterRef(
'result_form__center__code'),
station_number=OuterRef(
'result_form__station_number'))
.values('registrants')[:1],
output_field=IntegerField())

voters = Result.objects.filter(
result_form__tally__id=tally_id,
result_form__center__sub_constituency__code=data.get('municipality_code'),
result_form__ballot__electrol_race__ballot_name=data.get('sub_race_type'),
result_form__form_state=FormState.ARCHIVED,
entry_version=EntryVersion.FINAL,
active=True,
).annotate(
station_gender_code=result_station_gender_query,
station_registrants=result_station_registrants_query,
).filter(
station_gender_code=data.get('station_gender_code')
).aggregate(
voters=Coalesce(Sum('votes'), 0)
).get('voters')

municipality_name = data.get('municipality_name')
municipality_code = data.get('municipality_code')
sub_race = data.get('sub_race_type')
human = data.get('station_gender')
registrants = data.get('total_registrants')

turnout = round(100 * voters / registrants, 2)
# Write the data row
writer.writerow([
municipality_name,
municipality_code,
sub_race,
human,
voters,
registrants,
turnout,
])

print(f"CSV files has been created: {csv_filepath}")


class Command(BaseCommand):
help = gettext_lazy("get election turnout report by gender.")

def handle(self, *args, **kwargs):
self.get_election_turnout_report_by_gender()

def get_election_turnout_report_by_gender(self):
generate_csv()
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import csv
import pathlib

from django.core.management.base import BaseCommand
from django.utils.translation import gettext_lazy
from django.utils import timezone
from django.db.models import F, IntegerField, Subquery, OuterRef

from tally_ho.apps.tally.models.reconciliation_form import ReconciliationForm
from tally_ho.apps.tally.models.station import Station
from tally_ho.libs.models.enums.entry_version import EntryVersion
from tally_ho.libs.models.enums.form_state import FormState

def generate_csv():
tally_id = 1
station_id_query =\
Subquery(
Station.objects.filter(
tally__id=tally_id,
center__code=OuterRef(
'result_form__center__code'),
station_number=OuterRef(
'result_form__station_number'))
.values('id')[:1],
output_field=IntegerField())
station_registrants_query =\
Subquery(
Station.objects.filter(
tally__id=tally_id,
id=OuterRef(('station_id_num')))
.values('registrants')[:1],
output_field=IntegerField())
recon_forms =\
ReconciliationForm.objects.filter(
result_form__tally__id=tally_id,
result_form__form_state=FormState.ARCHIVED,
entry_version=EntryVersion.FINAL,
active=True
).annotate(
barcode=F('result_form__barcode'),
station_id_num=station_id_query
).values('barcode').annotate(
ballots_inside=F('number_ballots_inside_box'),
station_registrants=station_registrants_query,
station_id=F('station_id_num'),
station_number=F('result_form__station_number'),
center_code=F('result_form__center__code'),
sub_race_name=F('result_form__center__sub_constituency__name'),
sub_race_code=F('result_form__center__sub_constituency__code')
)
forms =\
[
recon_form for recon_form in recon_forms\
if recon_form.get(
'ballots_inside') > recon_form.get('station_registrants')
]

# Generate CSV file path with timestamp
timestamp = timezone.now().strftime('%Y%m%d_%H%M%S')
csv_filename = f'overvote_forms_{timestamp}.csv'
csv_filepath = pathlib.Path(csv_filename)

# Define the CSV column headers
headers = [
'barcode',
'center_code',
'station_number',
'ballots_inside',
'station_registrants',
'sub_race_name',
'sub_race_code',
]

with open(csv_filepath, mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(headers)

for form in forms:
barcode = form.get('barcode'),
center_code = form.get('center_code'),
station_number = form.get('station_number'),
ballots_inside = form.get('ballots_inside'),
station_registrants = form.get('station_registrants'),
sub_race_name = form.get('sub_race_name'),
sub_race_code = form.get('sub_race_code'),

# Write the data row
writer.writerow([
barcode[0],
center_code[0],
station_number[0],
ballots_inside[0],
station_registrants[0],
sub_race_name[0],
sub_race_code[0],
])

print(f"CSV files has been created: {csv_filepath}")


class Command(BaseCommand):
help = gettext_lazy("create csv file with overvotes.")

def handle(self, *args, **kwargs):
self.get_overvoted_result_forms_csv()

def get_overvoted_result_forms_csv(self):
generate_csv()
Loading

0 comments on commit 1196aa7

Please sign in to comment.