Skip to content

Commit

Permalink
Merge pull request #438 from onaio/fix-barcode-scanning-and-audit-pro…
Browse files Browse the repository at this point in the history
…cess

Fix barcode scanning and audit process
  • Loading branch information
JohnMwashuma authored Nov 13, 2024
2 parents 5259413 + acfbaee commit ab2cb17
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 182 deletions.
Binary file modified locale/ar/LC_MESSAGES/django.mo
Binary file not shown.
276 changes: 146 additions & 130 deletions locale/ar/LC_MESSAGES/django.po

Large diffs are not rendered by default.

30 changes: 0 additions & 30 deletions tally_ho/apps/tally/static/js/barcode_verify.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,7 @@
let barcodeNumber = "";

const barcode_scanner = (barcodeInputField) => {
let typingTimeout;

if (barcodeInputField) {
barcodeInputField.addEventListener("keypress", function (e) {
// Reset the timeout on each keypress
clearTimeout(typingTimeout);

if (e.key === "Enter") {
barcodeInputField.value = barcodeNumber;
barcodeInputField.readOnly = true;
barcodeNumber = ""; // Reset after a full scan is detected
} else if (!isNaN(e.key)) {
barcodeNumber += e.key; // Append numeric input
}

// Set a timeout to reset if no key is pressed in 200ms (example debounce time)
typingTimeout = setTimeout(() => {
barcodeNumber = "";
}, 200);
});
}
};

document.addEventListener("DOMContentLoaded", () => {
const barcodeScanInputField = document.getElementById("id_scanned_barcode");
const barcodeManualEntryInputField = document.getElementById("id_barcode");
const barcodeCopyManualEntryInputField = document.getElementById("id_barcode_copy");

barcodeNumber = "";
barcode_scanner(barcodeScanInputField);

// Set or remove required attributes based on form mode
barcodeScanInputField.setAttribute("required", "true");
barcodeManualEntryInputField.removeAttribute("required");
Expand Down
2 changes: 1 addition & 1 deletion tally_ho/apps/tally/templates/audit/print_cover.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h2>{% trans 'Audit Case: Team Page' %}</h2>
<td>{% trans 'Barcode Number:' %} </td><td>{{ result_form.barcode }}</td>
</tr>
<tr>
<td>{% trans 'Office Name:' %} </td><td>{{ result_form.center.office }}</td>
<td>{% trans 'Office Name:' %} </td><td>{{ result_form.center.office.name }}</td>
<td>{% trans 'Election Level:' %} </td><td>{{ result_form.ballot.electrol_race.election_level }}</td>
<td>{% trans 'Sub Race Type:' %} </td><td>{{ result_form.ballot.electrol_race.ballot_name }}</td>
</tr>
Expand Down
58 changes: 43 additions & 15 deletions tally_ho/apps/tally/templates/audit/review.html
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
{% extends 'base.html' %}

{% load i18n %}
{% load app_filters %}

{% block content %}

<div class="container main-container">
<h1>{% trans 'Audit:' %} {{ audit_type }}</h1>

<div class="row">
<h1>{% trans 'Audit:' %} {% if is_clerk %}{% trans 'Clerk Review' %}{% else %}{% trans 'Supervisor Review' %}{% endif %}</h1>
</div>
{% include 'center_details.html' %}

{% if result_form.audit %}
<h1>{% trans 'Quarantined Form' %}</h1>
<hr>
{% for check in result_form.audit.quarantine_checks.all %}
<p>
{% trans 'Failed quarantine check:' %}
<b>{{ check.local_name }}</b>
</p>
<br>
{% endfor %}
{% endif %}


<div class="row audit-form border-top">
<form name="audit" method="post" action="">
<div class="col-md-2 col-sm-1 grid2">
{% if result_form.audit %}
<h3>{% trans 'Quarantined Form' %}</h3>
{% for check in result_form.audit.quarantine_checks.all %}
<p>
{% trans 'Failed quarantine check:' %}
{{ check.local_name }}
</p>
{% endfor %}
{% endif %}
<h3>{% trans "Problem" %}</h3>
<p>{{ form.blank_reconciliation }}<label for="id_blank_reconciliation">{% trans "Blank reconciliation:" %}</label></p>
<p>{{ form.blank_results }}<label for="id_blank_results">{% trans "Blank results:" %}</label> </p>
Expand All @@ -44,17 +49,40 @@ <h3>{% trans "Action Prior to Recommendation" %}</h3>
<p><button class="btn btn-danger" type="submit" name="return">{% trans "Return to Audit Team" %}</button></p>
{% endif %}
</div>
{% if form.action_prior_to_recommendation.value|get_audit_action_name != '----' or form.action_prior_to_recommendation.value|get_audit_action_name != '----' %}
<div class="col-md-2 col-sm-1 grid2 righter">
{% if is_clerk %}
<p><label for="id_team_comment">{% trans "Team comment:" %}</label>
{{ form.team_comment }}
<h3>{% trans "Action Prior to Recommendation" %}</h3>
{% if form.action_prior_to_recommendation.value|get_audit_action_name != '----' %}
<p><label for="id_action_prior_to_recommendation">{% trans "Action prior to recommendation:" %}</label>
{{ form.action_prior_to_recommendation.value|get_audit_action_name }}
</p>
{% endif %}
{% if form.action_prior_to_recommendation.value|get_audit_action_name != '----' %}
<p><label for="id_resolution_recommendation">{% trans "Resolution recommendation:" %}</label>
{{ form.resolution_recommendation.value|get_audit_resolution_name }}
</p>
{% else %}
{% endif %}
</div>
{% endif %}
<div class="col-md-2 col-sm-1 grid2 righter">
{% if form.team_comment.value %}
<p><label for="id_team_comment">{% trans "Team comment:" %}</label>
{{ form.team_comment.value }}
</p>
{% endif %}
{% if not is_clerk %}
{% if form.supervisor_comment.value %}
<p><label for="id_supervisor_comment">{% trans "Supervisor comment:" %}</label>
{{ form.supervisor_comment.value }}
</p>
{% endif %}
{% endif %}
{% if is_clerk %}
<p><label for="id_team_comment">{% trans "Team comment:" %}</label>
{{ form.team_comment }}
</p>
{% endif %}
{% if not is_clerk %}
<p><label for="id_supervisor_comment">{% trans "Supervisor comment:" %}</label>
{{ form.supervisor_comment }}
</p>
Expand Down
5 changes: 3 additions & 2 deletions tally_ho/apps/tally/templates/center_details.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{% load i18n %}

<h3>{% trans 'Polling Center Details' %}</h3>
<div class="row">
<div class="container">
<h3>{% trans 'Polling Center Details' %}</h3>
<hr>

<table class="table table-bordered pull-left infotable">
<tr>
Expand All @@ -19,7 +20,7 @@ <h3>{% trans 'Polling Center Details' %}</h3>
</tr>
<tr>
<td width="40%">{% trans 'Office Name:' %}</td>
<td width="">{{ result_form.center.office }}</td>
<td width="">{{ result_form.center.office.name }}</td>
</tr>
<tr>
<td>{% trans 'Center Name:' %}</td>
Expand Down
2 changes: 1 addition & 1 deletion tally_ho/apps/tally/templates/clearance/print_cover.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h2>{% trans 'Clearance Case: Team Page' %}</h2>
<td>{% trans 'Barcode Number:' %} </td><td>{{ result_form.barcode }}</td>
</tr>
<tr>
<td>{% trans 'Office Name:' %} </td><td>{{ result_form.center.office }}</td>
<td>{% trans 'Office Name:' %} </td><td>{{ result_form.center.office.name }}</td>
<td>{% trans 'Election Level:' %} </td><td>{{ result_form.ballot.electrol_race.election_level }}</td>
<td>{% trans 'Sub Race Type:' %} </td><td>{{ result_form.ballot.electrol_race.ballot_name }}</td>
</tr>
Expand Down
9 changes: 9 additions & 0 deletions tally_ho/apps/tally/templates/print_cover_common.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
{% load i18n %}

<tr>
<td>{% trans 'Barcode:' %}</td><td>{{ result_form.barcode }}</td>
</tr>
<tr>
<td>{% trans 'Region Name:' %}</td><td>{{ result_form.center.office.region.name }}</td>
</tr>
<tr>
<td>{% trans 'Office Name:' %}</td><td>{{ result_form.center.office.name }}</td>
</tr>
<tr>
<td>{% trans 'Center Name:' %}</td><td>{{ result_form.center.name }}</td>
</tr>
Expand Down
1 change: 1 addition & 0 deletions tally_ho/apps/tally/templates/quality_control/results.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{% load i18n %}

<h2>{% trans header_text %} {% trans 'Results Section' %}</h2>
<hr>
<table class="table table-striped table-bordered">
<tr>
<th>{% trans 'No.' %}</th>
Expand Down
46 changes: 46 additions & 0 deletions tally_ho/apps/tally/templatetags/app_filters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django import template

from tally_ho.apps.tally.models.tally import Tally
from tally_ho.libs.models.enums.actions_prior import ActionsPrior
from tally_ho.libs.models.enums.audit_resolution import AuditResolution

register = template.Library()

Expand Down Expand Up @@ -42,3 +44,47 @@ def get_tally_name(tally_id):
pass

return tally_name

def get_action_prior_label_by_number(choice_number):
for number, choice_label in ActionsPrior.choices():
if number == choice_number:
return choice_label

@register.filter(name="get_audit_action_name")
def get_audit_action_name(action_prior_enum):
"""Get audit action name.
:param action_prior_enum: Audit prior enum
:returns: Action prior name as a String.
"""
action_prior_name = None
try:
action_prior_name =\
get_action_prior_label_by_number(action_prior_enum.value)
except AttributeError:
pass

return action_prior_name

def get_audti_resolution_label_by_number(choice_number):
for number, choice_label in AuditResolution.choices():
if number == choice_number:
return choice_label

@register.filter(name="get_audit_resolution_name")
def get_audit_resolution_name(audit_resolution_enum):
"""Get audit resolution name.
:param audit_resolution_enum: Audit resolution enum
:returns: Audit resolution name as a String.
"""
audit_resolution_name = None
try:
audit_resolution_name =\
get_audti_resolution_label_by_number(audit_resolution_enum.value)
except AttributeError:
pass

return audit_resolution_name
22 changes: 20 additions & 2 deletions tally_ho/apps/tally/views/audit.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import dateutil.parser
from django.core.serializers.json import json, DjangoJSONEncoder
from django.forms import model_to_dict
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from django.views.generic import FormView, TemplateView
Expand All @@ -9,9 +10,11 @@

from tally_ho.apps.tally.forms.audit_form import AuditForm
from tally_ho.apps.tally.forms.barcode_form import BarcodeForm
from tally_ho.apps.tally.forms.recon_form import ReconForm
from tally_ho.apps.tally.models.audit import Audit
from tally_ho.apps.tally.models.result_form import ResultForm
from tally_ho.apps.tally.models.result_form_stats import ResultFormStats
from tally_ho.apps.tally.views.quality_control import result_form_results
from tally_ho.libs.models.enums.audit_resolution import\
AuditResolution
from tally_ho.libs.models.enums.actions_prior import\
Expand Down Expand Up @@ -218,11 +221,19 @@ def get(self, *args, **kwargs):
self.request.session[
'encoded_result_form_audit_start_time'] =\
json.loads(json.dumps(timezone.now(), cls=DjangoJSONEncoder))
reconciliation_form = ReconForm(data=model_to_dict(
result_form.reconciliationform
)) if result_form.reconciliationform else None
results = result_form_results(result_form)

return self.render_to_response(self.get_context_data(
form=form, result_form=result_form,
form=form,
result_form=result_form,
is_clerk=is_clerk(self.request.user),
tally_id=tally_id))
tally_id=tally_id,
reconciliation_form=reconciliation_form,
results=results,
))

def post(self, *args, **kwargs):
tally_id = kwargs.get('tally_id')
Expand Down Expand Up @@ -360,6 +371,13 @@ def post(self, *args, **kwargs):
if groups.SUPER_ADMINISTRATOR in groups.user_groups(
self.request.user):
possible_states.append(FormState.ARCHIVED)
if result_form.audit is not None:
if (result_form.form_state == FormState.AUDIT) &\
(result_form.audited_count > 0) &\
(result_form.audit.action_prior_to_recommendation in\
[ActionsPrior.REQUEST_AUDIT_ACTION_FROM_FIELD,
ActionsPrior.REQUEST_COPY_FROM_FIELD]):
possible_states.append(FormState.AUDIT)

form = safe_form_in_state(result_form, possible_states, form)

Expand Down
18 changes: 18 additions & 0 deletions tally_ho/apps/tally/views/clearance.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ def clearance_action(post_data, clearance, result_form, url):
# take implementation action
clearance.reviewed_supervisor = True

if clearance.resolution_recommendation ==\
ClearanceResolution.PENDING_FIELD_INPUT:
clearance.active = True
result_form.form_state = FormState.CLEARANCE
result_form.save()

if clearance.resolution_recommendation ==\
ClearanceResolution.RESET_TO_PREINTAKE:
clearance.active = False
Expand Down Expand Up @@ -305,6 +311,12 @@ def post(self, *args, **kwargs):
self.request.user):
possible_states.append(FormState.ARCHIVED)

if result_form.clearance is not None:
if (result_form.form_state == FormState.CLEARANCE) &\
(result_form.clearance.resolution_recommendation ==\
ClearanceResolution.PENDING_FIELD_INPUT):
possible_states.append(FormState.CLEARANCE)

form = safe_form_in_state(result_form, possible_states, form)

if form:
Expand Down Expand Up @@ -372,6 +384,12 @@ def post(self, *args, **kwargs):
self.request.user):
possible_states.append(FormState.ARCHIVED)

if (result_form.form_state == FormState.CLEARANCE) &\
(result_form.clearance is not None) &\
(result_form.clearance.resolution_recommendation ==\
ClearanceResolution.PENDING_FIELD_INPUT):
possible_states.append(FormState.CLEARANCE)

form = safe_form_in_state(result_form, possible_states, form)

if form:
Expand Down
7 changes: 6 additions & 1 deletion tally_ho/apps/tally/views/quality_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,15 @@ def get(self, *args, **kwargs):

del self.request.session['result_form']

next_step =\
_('Audit') if result_form.form_state == FormState.AUDIT\
else _('Archiving')


return self.render_to_response(
self.get_context_data(result_form=result_form,
header_text=_('Quality Control'),
next_step=_('Archiving'),
next_step=next_step,
tally_id=tally_id,
start_url='quality-control'))

Expand Down

0 comments on commit ab2cb17

Please sign in to comment.