Files
scripts/cleaners/clean-halifax-actual.py~
2026-03-08 14:54:52 +00:00

85 lines
2.5 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
import csv
from decimal import Decimal, InvalidOperation
import sys
from pathlib import Path
def convert(in_path, out_path):
# Read Halifax CSV and write a cleaned CSV for Actual
with open(in_path, newline="", encoding="utf-8-sig") as f_in, \
open(out_path, "w", newline="", encoding="utf-8") as f_out:
reader = csv.DictReader(f_in)
# Output columns tailored for Actuals CSV import
fieldnames = ["Date", "Payee", "Description", "Amount"]
writer = csv.DictWriter(f_out, fieldnames=fieldnames)
writer.writeheader()
for row in reader:
if not row:
continue
# Date in Halifax export (dd/mm/yyyy)
date = (row.get("Transaction Date") or "").strip()
if not date:
# Skip lines without a date
continue
desc = (row.get("Transaction Description") or "").strip()
payee = desc or (row.get("Transaction Type") or "").strip()
# Halifax has separate Debit / Credit columns
debit_str = (row.get("Debit Amount") or "").replace(",", "").strip()
credit_str = (row.get("Credit Amount") or "").replace(",", "").strip()
amount = None
# Debits (money going out) → negative
if debit_str:
try:
amount = -Decimal(debit_str)
except InvalidOperation:
amount = None
# Credits (money coming in) → positive
elif credit_str:
try:
amount = Decimal(credit_str)
except InvalidOperation:
amount = None
# If we still don't have an amount, skip the row
if amount is None:
continue
writer.writerow({
"Date": date,
"Payee": payee,
"Description": desc,
"Amount": f"{amount:.2f}",
})
def main():
if len(sys.argv) < 2:
print("Usage: python clean_halifax_actual.py input.csv [output.csv]")
sys.exit(1)
in_path = Path(sys.argv[1])
if len(sys.argv) >= 3:
out_path = Path(sys.argv[2])
else:
# Default to inputname_actual.csv
out_path = in_path.with_name(in_path.stem + "_actual.csv")
convert(in_path, out_path)
print(f"Written cleaned file to {out_path}")
if __name__ == "__main__":
main()