From 5f801c99f3f004a5113a0da8054c2dd890d31f72 Mon Sep 17 00:00:00 2001 From: Ben Sturmfels Date: Thu, 22 Feb 2024 12:31:10 +1100 Subject: [PATCH] Fix :dev alias deps, ungroup employer-taxes data, avoid "super" lingo --- deps.edn | 2 +- src/import.clj | 86 ++++++++++++++++++++++++-------------------------- src/parse.clj | 4 ++- 3 files changed, 45 insertions(+), 47 deletions(-) diff --git a/deps.edn b/deps.edn index c6c05ac..0fa6d3c 100644 --- a/deps.edn +++ b/deps.edn @@ -3,7 +3,7 @@ org.clojure/data.csv {:mvn/version "1.0.1"} org.clojure/tools.cli {:mvn/version "1.1.230"}} :aliases - {:dev {:deps {lambdaisland/deep-diff2 {:mvn/version "2.10.211"}}} + {:dev {:extra-deps {lambdaisland/deep-diff2 {:mvn/version "2.10.211"}}} ;; Run with clj -T:build function-in-build :build {:deps {io.github.clojure/tools.build {:mvn/version "0.9.6"}} :ns-default build}}} diff --git a/src/import.clj b/src/import.clj index dbb685b..8b2cf39 100644 --- a/src/import.clj +++ b/src/import.clj @@ -141,7 +141,7 @@ "Return a transaction of expenses/witholding for each employee." [date period receipt-no invoice-no groups] (for [[name records] groups] - (let [super-lines (filter #(= (:type %) "Retirement") records) + (let [retirement-lines (filter #(= (:type %) "Retirement") records) ;; TODO: Have I got the liability/witholding right? Which is used in which report. witholding-lines (filter #(= (:type %) "Withholding") records) ;; TODO: We seem to add these extra expense/asset postings for @@ -149,23 +149,23 @@ ;; with Rosanne. insurance-lines (filter #(and (= (:type %) "Withholding") (str/starts-with? (:category %) "NY Disability")) records) - total-super (->> super-lines - (map :amount) - (apply +)) - super-postings (for [{:keys [category amount]} super-lines] - (if (= category "403b ER match") - {:account "Expenses:Payroll:Salary" - :amount amount - :currency "USD" - :meta {:payroll-type "US:403b:Match" - :invoice invoice-no}} - {:account "Expenses:Payroll:Salary" - :amount amount - :currency "USD" - :meta {:payroll-type "US:403b:Employee" - :invoice invoice-no}})) + total-retirement (->> retirement-lines + (map :amount) + (apply +)) + retirement-postings (for [{:keys [category amount]} retirement-lines] + (if (= category "403b ER match") + {:account "Expenses:Payroll:Salary" + :amount amount + :currency "USD" + :meta {:payroll-type "US:403b:Match" + :invoice invoice-no}} + {:account "Expenses:Payroll:Salary" + :amount amount + :currency "USD" + :meta {:payroll-type "US:403b:Employee" + :invoice invoice-no}})) liability-postings [{:account "Liabilities:Payable:Accounts" - :amount (- total-super) + :amount (- total-retirement) :currency "USD" :meta {:invoice invoice-no}}] withholding-postings (for [{:keys [category amount]} witholding-lines] @@ -192,7 +192,7 @@ :receipt receipt-no :approval "Financial/Employment-Records/memo-re-board-approval-of-payroll.txt"}) :postings (concat - super-postings + retirement-postings liability-postings withholding-postings withholding-asset-postings @@ -202,34 +202,30 @@ (defn employer-taxes "Return an employer taxes transaction." [date period receipt-no groups] - (let [liability-postings (apply concat - (for [[name records] groups] - (let [liability-lines (filter #(and (= (:type %) "Liability") - (not (str/includes? (:category %) "Unemploy"))) records)] - (for [{:keys [category amount]} liability-lines] - {:account "Expenses:Payroll:Tax" - :amount amount - :currency "USD" - ;; TODO: Check lack of ":Tax:" with Rosanne. - :meta (assoc-project - name - {:entity name - :payroll-type (str/replace (cat->payroll-type category) "Tax:" "")})})))) + (let [ungrouped (concat (vals groups)) ; Grouping by employee not useful here + liability-lines (filter #(and (= (:type %) "Liability") + (not (str/includes? (:category %) "Unemploy"))) ungrouped) + liability-postings (for [{:keys [category amount]} liability-lines] + {:account "Expenses:Payroll:Tax" + :amount amount + :currency "USD" + ;; TODO: Check lack of ":Tax:" with Rosanne. + :meta (assoc-project + name + {:entity name + :payroll-type (str/replace (cat->payroll-type category) "Tax:" "")})}) total-liabilities (->> liability-postings (map :amount) (reduce +)) - unemploy-postings (apply concat - (for [[name records] groups] - (let [unemploy-lines (filter #(and (= (:type %) "Liability") - (str/includes? (:category %) "Unemploy")) records)] - (for [{:keys [amount category]} unemploy-lines] - {:account "Expenses:Payroll:Tax" - :amount amount - :currency "USD" - :meta (assoc-project - name - {:entity (first (str/split category #" ")) - ;; TODO: Karen doesn't have a memo in January 2024 - :memo name - :payroll-type (str "US:" (cat->payroll-type category))})})))) + unemploy-lines (filter #(and (= (:type %) "Liability") + (str/includes? (:category %) "Unemploy")) ungrouped) + unemploy-postings (for [{:keys [amount category]} unemploy-lines] + {:account "Expenses:Payroll:Tax" + :amount amount + :currency "USD" + :meta (assoc-project + name + {:entity (first (str/split category #" ")) + :memo name ; TODO: Karen doesn't have a memo in January 2024 + :payroll-type (str "US:" (cat->payroll-type category))})}) total-unemploy (->> unemploy-postings (map :amount) (reduce +)) asset-postings [{:account "Assets:FR:Check2721" :amount (- (+ total-liabilities total-unemploy)) diff --git a/src/parse.clj b/src/parse.clj index 3c34f78..a0708fa 100644 --- a/src/parse.clj +++ b/src/parse.clj @@ -87,7 +87,9 @@ (defn parse "Parse a Beancount transaction into an intermediate data structure. Used in development to compare a hand-written Beancount import side-by-side - with an automatically generated import." + with an automatically generated import using deep-diff2. We can't directly + compare the text output because the ordering and spacing is too hard to get to + match exactly." [text] (let [tree (s/conform ::transactions (conj (vec text) \newline))] (convert-parse-tree tree)))