IMarvinTPA

Untitled

Dec 30th, 2025
469
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.66 KB | Source Code | 0 0
  1. # %%
  2. #Imports
  3. import actual as a
  4. from actual.queries import reconcile_transaction, get_account, match_transaction
  5. import pandas as pd
  6. import os, glob
  7. from dataclasses import dataclass
  8. from datetime import date
  9. import datetime
  10. import decimal
  11.  
  12. # %%
  13. #Configuraiton
  14.  
  15. srcDir = "/home/imarvintpa/Downloads"
  16. dstDir = "/home/imarvintpa/Documents/Budget/Dailies"
  17.  
  18. #functions.
  19. def getFiles(srcDir, pattern) -> list[str]:
  20.     searchPattern = os.path.join(srcDir, pattern)
  21.     files = glob.glob(searchPattern)
  22.     return files
  23.  
  24.  
  25. def getData(fileName, skip) -> pd.DataFrame:
  26.     df = pd.read_csv(fileName, skiprows=skip)
  27.     print(df.dtypes)
  28.     print(df)
  29.     return df
  30.  
  31.  
  32. #x = reconcile_transaction()
  33. @dataclass
  34. class ImportAccount:
  35.     acctId: str
  36.     filePattern: str
  37.     skip: int
  38.     date: str
  39.     dateFmt: str
  40.     payee: str
  41.     notes: str
  42.     amount: str
  43.     invertAmount: bool = False
  44.  
  45.  
  46. creditcard = ImportAccount("MasterCard",
  47.                         filePattern = "Card_*.csv",
  48.                         skip = 4,
  49.                         date = "Transaction Date",
  50.                         dateFmt = "%m/%d/%Y",
  51.                         payee = "Description",
  52.                         notes = "",
  53.                         amount = "Amount",
  54.                         )
  55.  
  56.  
  57. checking = ImportAccount("Checking",
  58.                         filePattern = "acct_chk_*.csv",
  59.                         skip = 0,
  60.                         date = "Transaction Date",
  61.                         dateFmt = "%m/%d/%Y",
  62.                         payee = "Full description",
  63.                         notes = "Category name",
  64.                         amount = "Amount",
  65.                         )
  66.  
  67. visa = ImportAccount("Visa",
  68.                         filePattern = "acct_visa_*.csv",
  69.                         skip = 0,
  70.                         date = "Transaction Date",
  71.                         dateFmt = "%m/%d/%y",
  72.                         payee = "Description",
  73.                         notes = "",
  74.                         amount = "Amount",
  75.                         invertAmount = True,
  76.                         )
  77.  
  78. importList = [creditcard, visa, checking]
  79.  
  80.  
  81. def doImport(actual: a.Actual, acct: ImportAccount):
  82.     files = getFiles(srcDir, acct.filePattern)
  83.     account = get_account(actual.session, acct.acctId)
  84.     for file in files:
  85.         print(file)
  86.         df = getData(file, acct.skip)
  87.         dataList = df.to_dict("records")
  88.         for e in dataList:
  89.             print("")
  90.             tDate = datetime.datetime.strptime(e[acct.date], acct.dateFmt).date()
  91.             payee = str(e[acct.payee]).title()
  92.             notes = None
  93.             if acct.notes in df.columns:
  94.                 notes = e[acct.notes]
  95.             amount: str = str(e[acct.amount])
  96.  
  97.             sign = 1
  98.             if acct.invertAmount:
  99.                 sign = 0 - sign
  100.  
  101.             if amount.startswith("(") and amount.endswith(")"):
  102.                 sign = 0 - sign
  103.                 amount = amount.replace("(", "").replace(")", "")
  104.  
  105.             amount = amount.replace("$", "")
  106.             amount = amount.replace(",", "")
  107.             #print(amount)
  108.             amount = decimal.Decimal(amount)
  109.             if sign < 0:
  110.                 amount = -amount
  111.  
  112.  
  113.             print(account.name, tDate, payee, amount, notes)
  114.             et = match_transaction(actual.session, tDate, account, payee, amount)
  115.             print(et)
  116.             if et is not None:
  117.                 #print(et.date, et.imported_description)
  118.                 if et.imported_description.lower() != payee.lower():
  119.                     #print(et.imported_description.lower(), payee.lower())
  120.                     #print("Name Not good enough for me.")
  121.                     et = None
  122.                 elif datetime.datetime.strptime(str(et.date), "%Y%m%d").date() != tDate:
  123.                     #print("Date Not good enough for me.")
  124.                     et = None
  125.             if et is None:
  126.                 t = reconcile_transaction(actual.session, tDate, account, None, notes, amount=amount, cleared=1, imported_payee=payee)
  127.                 print(t)
  128.                 print(t.changed())
  129.             else:
  130.                 print("Found")
  131.         actual.commit()
  132.         os.rename(file, os.path.join(dstDir, os.path.basename(file)))
  133.  
  134.  
  135.  
  136. # %%
  137. def doAllImports():
  138.     with a.Actual("https://actual.local/",
  139.                         password = "**********",
  140.                         file = "My Finances",
  141.                         data_dir = "./data",
  142.                         ) as actualAcct:
  143.         actualAcct.sync()
  144.         for act in importList:
  145.             doImport(actualAcct, act)
  146.  
  147. # %%
  148. if __name__ == "__main__":
  149.     doAllImports()
  150.  
Advertisement
Add Comment
Please, Sign In to add comment