poorly reconciled with additions to what we should do before launching
(assertions)
This commit is contained in:
parent
fd50dfec93
commit
9c5507523f
|
@ -1,3 +1,5 @@
|
||||||
|
This isn't the way to solve this problem
|
||||||
|
|
||||||
=====
|
=====
|
||||||
Rules
|
Rules
|
||||||
=====
|
=====
|
||||||
|
|
15
readme.rst
15
readme.rst
|
@ -4,16 +4,11 @@ Muneem
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
----
|
----
|
||||||
- [ ] Download Savings acct CSV
|
|
||||||
- [ ] Import Savings acct CSV
|
|
||||||
- [ ] RECONCILE
|
|
||||||
- [ ] Download NAB trade transactions and value
|
- [ ] Download NAB trade transactions and value
|
||||||
- [ ] Download spaceship returns
|
- [ ] Download spaceship returns
|
||||||
- [ ] `pad` checking / savings accounts against some known value way in the past
|
- [ ] MAYBE Mention uncategorized transactions in matrix chat so that i can categorize it
|
||||||
- [ ] 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
|
|
||||||
- [ ] Post weekly spending in matrix chat
|
- [ ] Post weekly spending in matrix chat
|
||||||
|
- [ ] Create assertion for each ingest to ensure we're tracking correctly
|
||||||
|
|
||||||
|
|
||||||
DONE
|
DONE
|
||||||
|
@ -24,6 +19,12 @@ DONE
|
||||||
- [x] Marshall the data into a way that bean count understands
|
- [x] Marshall the data into a way that bean count understands
|
||||||
- [x] Open accounts that previously didn't exist
|
- [x] Open accounts that previously didn't exist
|
||||||
- [x] Write the transactions to the file
|
- [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::
|
beancount::
|
||||||
|
|
||||||
|
|
|
@ -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/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)
|
(e/wait 3)
|
||||||
; Download savings file
|
; 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-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\")")
|
(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(\"#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/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)
|
(e/wait 3)
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
[clojure.java.io]
|
[clojure.java.io]
|
||||||
[cljc.java-time.local-date :as jt]
|
[cljc.java-time.local-date :as jt]
|
||||||
[cljc.java-time.format.date-time-formatter :as pt]
|
[cljc.java-time.format.date-time-formatter :as pt]
|
||||||
|
[clojure.java.shell :refer [sh]]
|
||||||
[clojure.string]))
|
[clojure.string]))
|
||||||
|
|
||||||
(def beancount-file "./documents/test.beancount")
|
(def beancount-file "./documents/ledger.beancount")
|
||||||
|
|
||||||
(def transaction-details (partial #(nth % 5)))
|
(def transaction-details (partial #(nth % 5)))
|
||||||
(def category (partial #(nth % 7)))
|
(def category (partial #(nth % 7)))
|
||||||
(defn merchant-name [trans]
|
(defn merchant-name [trans]
|
||||||
|
@ -130,9 +132,28 @@
|
||||||
(conj statement account-to)))
|
(conj statement account-to)))
|
||||||
|
|
||||||
(defn transfer-credit-account-to
|
(defn transfer-credit-account-to
|
||||||
[_ statement]
|
[trans statement]
|
||||||
(let [account-to (str " Assets:Savings")]
|
(let [account-to (str " Assets:Savings")
|
||||||
(conj statement account-to)))
|
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
|
(defn bank-credit-account-to
|
||||||
[_ statement]
|
[_ statement]
|
||||||
|
@ -188,11 +209,11 @@
|
||||||
else-account (str " Expenses:" (-> trans-type
|
else-account (str " Expenses:" (-> trans-type
|
||||||
(clojure.string/split #" ")
|
(clojure.string/split #" ")
|
||||||
(nth 1)))]
|
(nth 1)))]
|
||||||
(if (= amt 170)
|
(if (or (= amt 170) (= amt 540))
|
||||||
(conj statement rent)
|
(conj statement rent)
|
||||||
(conj statement else-account))))
|
(conj statement else-account))))
|
||||||
|
|
||||||
(defn transfer-debit-savings
|
(defn transfer-credit-savings
|
||||||
"This function is going to change a lot
|
"This function is going to change a lot
|
||||||
It currently only works with Expenses
|
It currently only works with Expenses
|
||||||
but in the future will need to handle determining account to"
|
but in the future will need to handle determining account to"
|
||||||
|
@ -201,10 +222,6 @@
|
||||||
(conj statement account-to)))
|
(conj statement account-to)))
|
||||||
|
|
||||||
;; RULES
|
;; RULES
|
||||||
; {:applies-to (fn [{trans-type :transaction-type
|
|
||||||
; amount :amount
|
|
||||||
; category :category
|
|
||||||
; merchant-name :merchant-name)))
|
|
||||||
|
|
||||||
(defn determine-category
|
(defn determine-category
|
||||||
"We probably want some sort of rule engine
|
"We probably want some sort of rule engine
|
||||||
|
@ -226,17 +243,15 @@
|
||||||
"ATM DEBIT" (atm-debit-account-to trans statement)
|
"ATM DEBIT" (atm-debit-account-to trans statement)
|
||||||
"DEPOSIT" (deposit-account-to trans statement)
|
"DEPOSIT" (deposit-account-to trans statement)
|
||||||
"INTER-BANK CREDIT" (bank-credit-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
|
(defn determine-category-savings
|
||||||
"We probably want some sort of rule engine
|
"The savings version of the above function (ugh)"
|
||||||
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"
|
|
||||||
[trans statement]
|
[trans statement]
|
||||||
(let [trans-type (transaction-type trans)]
|
(let [trans-type (transaction-type trans)]
|
||||||
(case trans-type
|
(case trans-type
|
||||||
|
"TRANSFER CREDIT" (transfer-credit-savings trans statement)
|
||||||
"TRANSFER DEBIT" (transfer-debit-savings trans statement)
|
"TRANSFER DEBIT" (transfer-debit-savings trans statement)
|
||||||
"INTEREST PAID" (interest-savings trans statement)
|
"INTEREST PAID" (interest-savings trans statement)
|
||||||
"INTER-BANK CREDIT" (bank-credit-account-to trans statement)
|
"INTER-BANK CREDIT" (bank-credit-account-to trans statement)
|
||||||
|
@ -274,7 +289,18 @@
|
||||||
(swap! new-accounts conj marshalled-from-account))
|
(swap! new-accounts conj marshalled-from-account))
|
||||||
transaction))
|
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
|
(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]
|
[transaction]
|
||||||
(->> []
|
(->> []
|
||||||
(make-date transaction)
|
(make-date transaction)
|
||||||
|
@ -283,9 +309,7 @@
|
||||||
(organize-correctly)
|
(organize-correctly)
|
||||||
(add-account-from-and-amount transaction)
|
(add-account-from-and-amount transaction)
|
||||||
(determine-category transaction)
|
(determine-category transaction)
|
||||||
#_(tap)
|
(do-we-continue?)))
|
||||||
(create-account)
|
|
||||||
(write-statement)))
|
|
||||||
|
|
||||||
(defn write-transaction-to-file-savings
|
(defn write-transaction-to-file-savings
|
||||||
[transaction]
|
[transaction]
|
||||||
|
@ -295,10 +319,8 @@
|
||||||
(add-narration transaction)
|
(add-narration transaction)
|
||||||
(organize-correctly)
|
(organize-correctly)
|
||||||
(add-account-from-and-amount-savings transaction)
|
(add-account-from-and-amount-savings transaction)
|
||||||
(determine-category transaction)
|
(determine-category-savings transaction)
|
||||||
#_(tap)
|
(do-we-continue?)))
|
||||||
(create-account)
|
|
||||||
(write-statement)))
|
|
||||||
|
|
||||||
(defn index-of [x coll]
|
(defn index-of [x coll]
|
||||||
(let [idx? (fn [i a] (when (= x a) i))]
|
(let [idx? (fn [i a] (when (= x a) i))]
|
||||||
|
@ -328,6 +350,8 @@
|
||||||
(str "2016-01-01 open " account))
|
(str "2016-01-01 open " account))
|
||||||
|
|
||||||
(defn write-accounts
|
(defn write-accounts
|
||||||
|
" TODO
|
||||||
|
this function doesn't look at @accounts..."
|
||||||
[ledger]
|
[ledger]
|
||||||
(let [file-contents (slurp ledger)
|
(let [file-contents (slurp ledger)
|
||||||
split (clojure.string/split file-contents #"\n")
|
split (clojure.string/split file-contents #"\n")
|
||||||
|
@ -337,10 +361,15 @@
|
||||||
full-file (vec (concat before middle after "\n"))]
|
full-file (vec (concat before middle after "\n"))]
|
||||||
(spit ledger (clojure.string/join "\n" full-file))))
|
(spit ledger (clojure.string/join "\n" full-file))))
|
||||||
|
|
||||||
|
(defn move-beancount-file
|
||||||
|
[]
|
||||||
|
(sh "cp" beancount-file "/home/anish/usr/finance/"))
|
||||||
|
|
||||||
(defn main
|
(defn main
|
||||||
[csv checking? & _args]
|
[csv checking? & _args]
|
||||||
(read-accounts beancount-file)
|
(read-accounts beancount-file)
|
||||||
(if checking?
|
(if checking?
|
||||||
(mapv write-transaction-to-file (drop-last (take-csv csv)))
|
(mapv write-transaction-to-file (drop-last (take-csv csv)))
|
||||||
(mapv write-transaction-to-file-savings (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 #{}))
|
||||||
|
|
|
@ -6,7 +6,14 @@
|
||||||
[& _args]
|
[& _args]
|
||||||
(download/download-csv)
|
(download/download-csv)
|
||||||
(download/move-download)
|
(download/move-download)
|
||||||
#_(import/main "./documents/checking.csv" true)
|
(import/main "./documents/checking.csv" true)
|
||||||
#_(import/main "./documents/savings.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))
|
||||||
|
|
Loading…
Reference in a new issue