from beancount.ingest.importer import ImporterProtocol
from beancount.core import data
from beancount.core import amount
from beancount.core.number import D
from dateutil.parser import parse
import datetime
import csv
import re
import logging
import warnings
from beancount.core import flags
class PNCChecking(ImporterProtocol):
def __init__(self, account, currency="USD"):
self.account = account
self.currency = currency
super().__init__()
def identify(self, file):
# Check if the file name contains "pnc checking" and ends with ".csv"
if "pnc checking" in file.name.lower() and file.name.lower().endswith('.csv'):
return True
else:
return False
def file_account(self, file):
return self.account
def extract(self, file):
entries = []
with open(file.name) as infile:
reader = csv.reader(infile)
next(reader, None) # Skip the header row
for index, row in enumerate(reader):
if len(row) < 5: # Checking if the row has at least 5 elements
logging.warning("Row %d does not have enough elements. Skipping.", index)
continue
meta = data.new_metadata(file.name, index) # Beancount meta
date = datetime.datetime.strptime(row[0], "%m/%d/%Y").date() # Parse the date of the transaction
# Extracting relevant information from the description to determine payee and other_account
description = row[1] # Assuming description is in the second column
payee = "" # Placeholder, modify this based on the description
other_account = "Expenses" # Placeholder, modify this based on the description
# Check if the description contains "CARD PMT"
if "CARD PMT" in description:
payee = "PNC Cash Rewards"
other_account = "Liabilities:PNC:CashRewards"
# Check if this is an ATM withdrawal
# and then subtract their ATM Fee and put that in separate expense
if "ATM" in description:
other_account = "Assets:Cash"
# Determining the credit/debit type based on withdrawals and deposits
withdrawal = row[2] # Withdrawals amount
deposit = row[3] # Deposits amount
if withdrawal:
units = -amount.Amount(D(withdrawal.replace('$', '')), self.currency) # Using withdrawal amount
elif deposit:
units = amount.Amount(D(deposit.replace('$', '')), self.currency) # Using deposit amount
else:
logging.warning("Invalid row: %s", row)
continue
account = self.account # Modify this according to your data
txn = data.Transaction(
meta,
date,
None, # No specific flag
payee,
description,
data.EMPTY_SET,
data.EMPTY_SET,
[
data.Posting(
account, units, None, None, None, None
),
data.Posting(
other_account, -units, None, None, None, None
),
],
)
entries.append(txn)
return entries