From 9c5507523f161302afae41541c2a6c8e739fe7bc Mon Sep 17 00:00:00 2001 From: Anish Lakhwara Date: Wed, 30 Nov 2022 23:19:03 +1000 Subject: [PATCH] poorly reconciled with additions to what we should do before launching (assertions) --- docs/how-to-rules.rst | 2 ++ readme.rst | 15 ++++---- src/muneem/etaoin.clj | 6 ++-- src/muneem/import.clj | 79 +++++++++++++++++++++++++++++-------------- src/muneem/main.clj | 13 +++++-- 5 files changed, 78 insertions(+), 37 deletions(-) diff --git a/docs/how-to-rules.rst b/docs/how-to-rules.rst index 248a4b0..637d83f 100644 --- a/docs/how-to-rules.rst +++ b/docs/how-to-rules.rst @@ -1,3 +1,5 @@ +This isn't the way to solve this problem + ===== Rules ===== diff --git a/readme.rst b/readme.rst index ccb62e3..7a76a66 100644 --- a/readme.rst +++ b/readme.rst @@ -4,16 +4,11 @@ Muneem TODO ---- -- [ ] Download Savings acct CSV -- [ ] Import Savings acct CSV -- [ ] RECONCILE - [ ] Download NAB trade transactions and value - [ ] Download spaceship returns -- [ ] `pad` checking / savings accounts against some known value way in the past -- [ ] MAYBE gonna have to write a rule engine that handles this -- [ ] MAYBE Parse the transaction only once at the start, and then use the parsed map instead of passing around a vector of strings -- [ ] Mention uncategorized transactions in matrix chat so that i can categorize it +- [ ] MAYBE Mention uncategorized transactions in matrix chat so that i can categorize it - [ ] Post weekly spending in matrix chat +- [ ] Create assertion for each ingest to ensure we're tracking correctly DONE @@ -24,6 +19,12 @@ DONE - [x] Marshall the data into a way that bean count understands - [x] Open accounts that previously didn't exist - [x] Write the transactions to the file +- [x] `pad` checking / savings accounts against some known value way in the past +- [x] MAYBE gonna have to write a rule engine that handles this +- [x] MAYBE Parse the transaction only once at the start, and then use the parsed map instead of passing around a vector of strings +- [x] Download Savings acct CSV +- [x] Import Savings acct CSV +- [x] RECONCILE beancount:: diff --git a/src/muneem/etaoin.clj b/src/muneem/etaoin.clj index 7065dc8..0f52877 100644 --- a/src/muneem/etaoin.clj +++ b/src/muneem/etaoin.clj @@ -31,8 +31,10 @@ (e/js-execute driver "document.querySelector(\"#bodyContent > miniapp-transactions\").shadowRoot.querySelector(\"div > div > div > div:nth-child(2) > div > div > div > div > div.StyledScreenView-jlloJx.gsnnCS > div > div > div > div.StyledTopRow-cijGbF.StyledExportCol-fYxmhQ.ibndGm.cAjmIO.sc-dkPtRN.Colstyle__StyledCol-sc-1evc4kf-0.ketKXK.fqofCs > div > div > div > ul > li:nth-child(1) > button\").click()") (e/wait 3) ; Download savings file - (e/js-execute driver "document.querySelector(\"#bodyContent > miniapp-transactions\").shadowRoot.querySelector(\"#dropdown-toggle-button-accountsListDropdown > div > div > div\")") - (e/js-execute driver "document.querySelector(\"#bodyContent > miniapp-transactions\").shadowRoot.querySelector(\"#dropdown-listbox-accountsListDropdown-1 > div > div > div.AccountCardstyle__StyledAccountTypeContainer-sc-16p3i3w-1.cLXpwB\")") + (e/js-execute driver "document.querySelector(\"#bodyContent > miniapp-transactions\").shadowRoot.querySelector(\"#dropdown-toggle-button-accountsListDropdown > div\").click()") + (e/js-execute driver "document.querySelector(\"#bodyContent > miniapp-transactions\").shadowRoot.querySelector(\"#dropdown-listbox-accountsListDropdown-1 > div > div > div.AccountCardstyle__StyledAccountTypeContainer-sc-16p3i3w-1.cLXpwB\").click()") + (e/js-execute driver "document.querySelector(\"#bodyContent > miniapp-transactions\").shadowRoot.querySelector(\"div > div > div > div.Containerstyle__StyledWrapper-sc-10ei1r0-0.dnudTa > div > div > div > div.StyledScreenView-jlloJx.gsnnCS > form > div > div:nth-child(3) > div > button\").click()") + (e/wait 3) (e/js-execute driver "document.querySelector(\"#bodyContent > miniapp-transactions\").shadowRoot.querySelector(\"#export-button > div\").click()") (e/js-execute driver "document.querySelector(\"#bodyContent > miniapp-transactions\").shadowRoot.querySelector(\"div > div > div > div:nth-child(2) > div > div > div > div > div.StyledScreenView-jlloJx.gsnnCS > div > div > div > div.StyledTopRow-cijGbF.StyledExportCol-fYxmhQ.ibndGm.cAjmIO.sc-dkPtRN.Colstyle__StyledCol-sc-1evc4kf-0.ketKXK.fqofCs > div > div > div > ul > li:nth-child(1) > button\").click()") (e/wait 3) diff --git a/src/muneem/import.clj b/src/muneem/import.clj index a9e0e85..906f7c2 100644 --- a/src/muneem/import.clj +++ b/src/muneem/import.clj @@ -3,9 +3,11 @@ [clojure.java.io] [cljc.java-time.local-date :as jt] [cljc.java-time.format.date-time-formatter :as pt] + [clojure.java.shell :refer [sh]] [clojure.string])) -(def beancount-file "./documents/test.beancount") +(def beancount-file "./documents/ledger.beancount") + (def transaction-details (partial #(nth % 5))) (def category (partial #(nth % 7))) (defn merchant-name [trans] @@ -130,9 +132,28 @@ (conj statement account-to))) (defn transfer-credit-account-to - [_ statement] - (let [account-to (str " Assets:Savings")] - (conj statement account-to))) + [trans statement] + (let [account-to (str " Assets:Savings") + income (str " ! Income:Other") + details (transaction-details trans) + category (category trans)] + (println category) + (if (= category "Transfers in") + (conj statement income) + (if (boolean (re-find #".*Linked Acc.*" details)) + (conj statement account-to) + (conj statement income))))) + +(defn transfer-debit-savings + "This function is going to change a lot + It currently only works with Expenses + but in the future will need to handle determining account to" + [trans statement] + (let [details (transaction-details trans) + account-to " ! Expenses:Uncategorised:From-Savings"] + (if (boolean (re-find #".*Linked Acc.*" details)) + nil ; these are the ones we want to skip, we accounted for them in checking + (conj statement account-to)))) (defn bank-credit-account-to [_ statement] @@ -188,11 +209,11 @@ else-account (str " Expenses:" (-> trans-type (clojure.string/split #" ") (nth 1)))] - (if (= amt 170) + (if (or (= amt 170) (= amt 540)) (conj statement rent) (conj statement else-account)))) -(defn transfer-debit-savings +(defn transfer-credit-savings "This function is going to change a lot It currently only works with Expenses but in the future will need to handle determining account to" @@ -201,10 +222,6 @@ (conj statement account-to))) ;; RULES -; {:applies-to (fn [{trans-type :transaction-type -; amount :amount -; category :category -; merchant-name :merchant-name))) (defn determine-category "We probably want some sort of rule engine @@ -226,17 +243,15 @@ "ATM DEBIT" (atm-debit-account-to trans statement) "DEPOSIT" (deposit-account-to trans statement) "INTER-BANK CREDIT" (bank-credit-account-to trans statement) - "MISCELLANEOUS CREDIT" (misc-credit-account-to trans statement)))) + "MISCELLANEOUS CREDIT" (misc-credit-account-to trans statement) + nil))) ; this should really be handled better, for "types" we haven't accounted for (debit rate going up?!? 21 NOV 2022) -(defn determine-category - "We probably want some sort of rule engine - that takes rules and applies the first match or something (see docs) - but this will do for now - - Writes out the account-to to the statement" +(defn determine-category-savings + "The savings version of the above function (ugh)" [trans statement] (let [trans-type (transaction-type trans)] (case trans-type + "TRANSFER CREDIT" (transfer-credit-savings trans statement) "TRANSFER DEBIT" (transfer-debit-savings trans statement) "INTEREST PAID" (interest-savings trans statement) "INTER-BANK CREDIT" (bank-credit-account-to trans statement) @@ -274,7 +289,18 @@ (swap! new-accounts conj marshalled-from-account)) transaction)) +(defn do-we-continue? + "we need to do some fuckery because we're handling nil as the case where we don't want to write anything + It's sorta an escape hatch, or the break point" + [continue?] + (if (not (nil? continue?)) + (->> continue? + (create-account) + (write-statement)))) + (defn write-transaction-to-file + "Please re-write this function so that make-date returns a map instead of a list, + it should be a parsed data structure with the statement as one of the keys" [transaction] (->> [] (make-date transaction) @@ -283,9 +309,7 @@ (organize-correctly) (add-account-from-and-amount transaction) (determine-category transaction) - #_(tap) - (create-account) - (write-statement))) + (do-we-continue?))) (defn write-transaction-to-file-savings [transaction] @@ -295,10 +319,8 @@ (add-narration transaction) (organize-correctly) (add-account-from-and-amount-savings transaction) - (determine-category transaction) - #_(tap) - (create-account) - (write-statement))) + (determine-category-savings transaction) + (do-we-continue?))) (defn index-of [x coll] (let [idx? (fn [i a] (when (= x a) i))] @@ -328,6 +350,8 @@ (str "2016-01-01 open " account)) (defn write-accounts + " TODO + this function doesn't look at @accounts..." [ledger] (let [file-contents (slurp ledger) split (clojure.string/split file-contents #"\n") @@ -337,10 +361,15 @@ full-file (vec (concat before middle after "\n"))] (spit ledger (clojure.string/join "\n" full-file)))) +(defn move-beancount-file + [] + (sh "cp" beancount-file "/home/anish/usr/finance/")) + (defn main [csv checking? & _args] (read-accounts beancount-file) (if checking? (mapv write-transaction-to-file (drop-last (take-csv csv))) (mapv write-transaction-to-file-savings (drop-last (take-csv csv)))) - (write-accounts beancount-file)) + (write-accounts beancount-file) + (reset! new-accounts #{})) diff --git a/src/muneem/main.clj b/src/muneem/main.clj index c412857..f194636 100644 --- a/src/muneem/main.clj +++ b/src/muneem/main.clj @@ -6,7 +6,14 @@ [& _args] (download/download-csv) (download/move-download) - #_(import/main "./documents/checking.csv" true) - #_(import/main "./documents/savings.csv" true)) + (import/main "./documents/checking.csv" true) + (import/main "./documents/savings.csv" false) + (import/move-beancount-file)) -(-main) +(comment + (import/main "./documents/checking-last-year.csv" true) + (import/main "./documents/checking-this-year.csv" true) + (import/main "./documents/savings-last-year.csv" false) + (import/main "./documents/savings-this-year.csv" false) + + (-main))