Skip to content

Commit

Permalink
Improve error message for duplicate barcodes check and add check for …
Browse files Browse the repository at this point in the history
…missing center codes
  • Loading branch information
JohnMwashuma committed Nov 6, 2024
1 parent 83742bd commit 092d1ca
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 6 deletions.
15 changes: 10 additions & 5 deletions tally_ho/apps/tally/management/commands/import_result_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
build_generic_model_key_values_from_duckdb_row_tuple_data,
check_duplicates,
check_for_missing_columns,
find_missing_center_codes,
get_ballot_by_ballot_number,
get_office_by_office_name_and_region_name,
)
Expand Down Expand Up @@ -200,6 +201,15 @@ def async_import_results_forms_from_result_forms_file(
csv_file_path=file_path,
field='barcode'
)
centers_by_code =\
{
center.code:\
center for center in Center.objects.filter(tally=tally)
}
find_missing_center_codes(
result_forms_file=file_path,
centers_by_code=centers_by_code
)

stations_by_number_underscore_center_code =\
{
Expand All @@ -211,11 +221,6 @@ def async_import_results_forms_from_result_forms_file(
ballot.number:\
ballot for ballot in Ballot.objects.filter(tally=tally)
}
centers_by_code =\
{
center.code:\
center for center in Center.objects.filter(tally=tally)
}
offices_by_name_underscore_region_name =\
{
f'{office.name}_{office.region.name}':\
Expand Down
55 changes: 54 additions & 1 deletion tally_ho/apps/tally/management/commands/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,19 @@ def check_for_missing_columns(
raise Exception(error_message)
return None

class DuplicatesFoundError(Exception):
"""Exception raised when duplicates are found in a CSV file based on
a specified field."""
def __init__(self, field, duplicates):
self.field = field
self.duplicates = duplicates
message = (
f"Duplicate entries detected in the '{field}' column: "
f"{', '.join(map(str, duplicates))}."
"Please ensure these values are unique."
)
super().__init__(message)

def check_duplicates(csv_file_path: str, field: str) -> None:
"""
Checks for duplicates in a CSV file based on a specified field using
Expand Down Expand Up @@ -256,11 +269,51 @@ def check_duplicates(csv_file_path: str, field: str) -> None:
query = """
SELECT {field}, COUNT(*) AS cnt
FROM read_csv_auto(?)
WHERE {field} IS NOT NULL AND {field} != ''
GROUP BY {field}
HAVING cnt > 1
""".format(field=field)

result = con.execute(query, [csv_file_path]).fetchall()
con.close()

if len(result) > 0:
raise Exception(f"Duplicates found for field '{field}'")
duplicate_values = [row[0] for row in result]
raise DuplicatesFoundError(field, duplicate_values)


class CenterCodeNotFoundException(Exception):
def __init__(self, center_codes):
self.center_codes = center_codes
self.message = (
"The following center codes do not exist in the centers file: "
f"{', '.join(map(str, center_codes))}"
)
super().__init__(self.message)

def find_missing_center_codes(result_forms_file, centers_by_code):
center_codes_list = list(centers_by_code.keys())

con = duckdb.connect()

center_codes_tuple = tuple(center_codes_list)

query = f"""
SELECT rf.center_code
FROM read_csv_auto('{result_forms_file}') AS rf
WHERE rf.center_code NOT IN {center_codes_tuple};
"""

# Execute the query and fetch the result
result = con.execute(query).fetchall()

# Close the connection
con.close()

# Extract the missing center codes
missing_center_codes = [row[0] for row in result]

# Raise the exception if there are any missing center codes
if missing_center_codes:
print(f"center codes: {missing_center_codes}")
raise CenterCodeNotFoundException(missing_center_codes)

0 comments on commit 092d1ca

Please sign in to comment.