Add example data and test, fix ungrouping, extend docs

This commit is contained in:
Ben Sturmfels 2024-02-22 14:06:45 +11:00
parent b4b42b72aa
commit 47cabfb0a9
Signed by: bsturmfels
GPG key ID: 023C05E2C9C068F0
5 changed files with 82 additions and 4 deletions

View file

@ -1,5 +1,9 @@
# Paychex payroll importer for Beancount
The aim of this tool is to automate the monthly task of transcribing payroll CSV
information for Conservancy's 8 (currently) employees into ~ 300 lines of fairly
intricate Beancount bookkeeping data.
## Usage
Run with:
@ -16,6 +20,10 @@ Or use a reduced set of options (missing values will be replaced by "TODO" in th
The project is set up for development in Emacs and CIDER-mode. Open a source
file and run `cider-jack-in`.
Run tests with:
clojure -M:test
You can run without building using:
clojure -M -m core --csv 2023-12-27_Pay-Item-Details_2023-12-2.csv --date 2023-12-29 --period "December 2023" --total-fees 206.50

View file

@ -1,9 +1,12 @@
{:deps {
{:paths ["src" "resources"]
:deps {
org.clojure/clojure {:mvn/version "1.11.1"}
org.clojure/data.csv {:mvn/version "1.0.1"}
org.clojure/tools.cli {:mvn/version "1.1.230"}}
:aliases
{:dev {:extra-deps {lambdaisland/deep-diff2 {:mvn/version "2.10.211"}}}
:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.87.1366"}}
:main-opts ["-m" "kaocha.runner"]}
;; Run with clj -T:build function-in-build
:build {:deps {io.github.clojure/tools.build {:mvn/version "0.9.6"}}
:ns-default build}}}

View file

@ -0,0 +1,28 @@
Example Co Inc,"Citizen, Jack A",1,403b EE Pretax,Retirement,,,,,,1000,,,,,
Example Co Inc,"Citizen, Jack A",1,Exp Reimb Non Tax,Reimbursement,,,,,50,,,,,,
Example Co Inc,"Citizen, Jack A",1,Fed Income Tax,Withholding,,,,,,,,470.22,,,
Example Co Inc,"Citizen, Jack A",1,Fed Unemploy,Liability,,,,,,,,,0,,
Example Co Inc,"Citizen, Jack A",1,Medicare,Withholding,,,,,,,,88,,,
Example Co Inc,"Citizen, Jack A",1,Medicare,Liability,,,,,,,,,88,,
Example Co Inc,"Citizen, Jack A",1,Net Pay,Net Pay,,,,,,,,,,,4184.49
Example Co Inc,"Citizen, Jack A",1,Salary,Earnings,6068.99,,0,,,,,,,,
Example Co Inc,"Citizen, Jack A",1,Social Security,Withholding,,,,,,,,376.28,,,
Example Co Inc,"Citizen, Jack A",1,Social Security,Liability,,,,,,,,,376.28,,
Example Co Inc,"Citizen, Jack A",1,TN Unemploy,Liability,,,,,,,,,0,,
Example Co Inc,"Citizen, Jill B",2,403b EE Pretax,Retirement,,,,,,820,,,,,
Example Co Inc,"Citizen, Jill B",2,Exp Reimb Non Tax,Reimbursement,,,,,50,,,,,,
Example Co Inc,"Citizen, Jill B",2,Fed Income Tax,Withholding,,,,,,,,681.01,,,
Example Co Inc,"Citizen, Jill B",2,Fed Unemploy,Liability,,,,,,,,,0,,
Example Co Inc,"Citizen, Jill B",2,Medicare,Liability,,,,,,,,,99.28,,
Example Co Inc,"Citizen, Jill B",2,Medicare,Withholding,,,,,,,,99.29,,,
Example Co Inc,"Citizen, Jill B",2,Net Pay,Net Pay,,,,,,,,,,,4397.39
Example Co Inc,"Citizen, Jill B",2,OR Disability PFL,Withholding,,,,,,,,41.08,,,
Example Co Inc,"Citizen, Jill B",2,OR Disability PFL,Liability,,,,,,,,,0,,
Example Co Inc,"Citizen, Jill B",2,OR EE Work Bene,Withholding,,,,,,,,0,,,
Example Co Inc,"Citizen, Jill B",2,OR ER Work Bene,Liability,,,,,,,,,0,,
Example Co Inc,"Citizen, Jill B",2,OR Income Tax,Withholding,,,,,,,,427.8,,,
Example Co Inc,"Citizen, Jill B",2,OR TRANS STT,Withholding,,,,,,,,6.03,,,
Example Co Inc,"Citizen, Jill B",2,OR Unemploy,Liability,,,,,,,,,0,,
Example Co Inc,"Citizen, Jill B",2,Salary,Earnings,6847.12,,0,,,,,,,,
Example Co Inc,"Citizen, Jill B",2,Social Security,Liability,,,,,,,,,424.52,,
Example Co Inc,"Citizen, Jill B",2,Social Security,Withholding,,,,,,,,424.52,,,
1 Example Co Inc Citizen, Jack A 1 403b EE Pretax Retirement 1000
2 Example Co Inc Citizen, Jack A 1 Exp Reimb Non Tax Reimbursement 50
3 Example Co Inc Citizen, Jack A 1 Fed Income Tax Withholding 470.22
4 Example Co Inc Citizen, Jack A 1 Fed Unemploy Liability 0
5 Example Co Inc Citizen, Jack A 1 Medicare Withholding 88
6 Example Co Inc Citizen, Jack A 1 Medicare Liability 88
7 Example Co Inc Citizen, Jack A 1 Net Pay Net Pay 4184.49
8 Example Co Inc Citizen, Jack A 1 Salary Earnings 6068.99 0
9 Example Co Inc Citizen, Jack A 1 Social Security Withholding 376.28
10 Example Co Inc Citizen, Jack A 1 Social Security Liability 376.28
11 Example Co Inc Citizen, Jack A 1 TN Unemploy Liability 0
12 Example Co Inc Citizen, Jill B 2 403b EE Pretax Retirement 820
13 Example Co Inc Citizen, Jill B 2 Exp Reimb Non Tax Reimbursement 50
14 Example Co Inc Citizen, Jill B 2 Fed Income Tax Withholding 681.01
15 Example Co Inc Citizen, Jill B 2 Fed Unemploy Liability 0
16 Example Co Inc Citizen, Jill B 2 Medicare Liability 99.28
17 Example Co Inc Citizen, Jill B 2 Medicare Withholding 99.29
18 Example Co Inc Citizen, Jill B 2 Net Pay Net Pay 4397.39
19 Example Co Inc Citizen, Jill B 2 OR Disability PFL Withholding 41.08
20 Example Co Inc Citizen, Jill B 2 OR Disability PFL Liability 0
21 Example Co Inc Citizen, Jill B 2 OR EE Work Bene Withholding 0
22 Example Co Inc Citizen, Jill B 2 OR ER Work Bene Liability 0
23 Example Co Inc Citizen, Jill B 2 OR Income Tax Withholding 427.8
24 Example Co Inc Citizen, Jill B 2 OR TRANS STT Withholding 6.03
25 Example Co Inc Citizen, Jill B 2 OR Unemploy Liability 0
26 Example Co Inc Citizen, Jill B 2 Salary Earnings 6847.12 0
27 Example Co Inc Citizen, Jill B 2 Social Security Liability 424.52
28 Example Co Inc Citizen, Jill B 2 Social Security Withholding 424.52

View file

@ -99,6 +99,26 @@
(str/join (for [[k v] meta]
(format " %s: \"%s\"\n" (name k) v)))))))))
;; Each of the below functions returns one of the five sections of the required
;; bookkeeping data:
;;
;; * net pay (single transaction)
;; * individual taxes (one transaction for each employee)
;; * employer taxes (single transaction)
;; * fees (single transaction)
;; * retirement (single trasaction)
;;
;; These functions take the input CSV data, pre-formatted and grouped by
;; employee.
;;
;; The output is an intermediate data structure that can then be run through
;; `render-transaction` to produce Beancount transaction text. The data
;; structures can also be programatically compared to a parsed version of the
;; hand-written Beancount transactions for development and testing (see
;; parse.clj).
;;
;; (All functions return a sequence of transactions so we can concatenate them.)
(defn payroll
"Return a net pay transaction."
[date period receipt-no groups]
@ -201,10 +221,10 @@
(defn employer-taxes
"Return an employer taxes transaction."
[date period receipt-no groups]
(let [ungrouped (concat (vals groups)) ; Grouping by employee not useful here
(let [ungrouped (apply 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]
liability-postings (for [{:keys [name category amount]} liability-lines]
{:account "Expenses:Payroll:Tax"
:amount amount
:currency "USD"

19
test/import_test.clj Normal file
View file

@ -0,0 +1,19 @@
(ns import-test
(:require [import :as sut]
[clojure.java.io]
[clojure.test :as t]))
(t/deftest sample-import
(let [grouped-data (import/read-grouped-csv
(clojure.java.io/resource
"example-paychex-pay-item-details.csv"))
imported (concat (import/payroll "2023-12-29" "December 2023" "rt:19462/674660" grouped-data)
(import/individual-taxes "2023-12-29" "December 2023" "rt:19462/674660" "rt:19403/675431" grouped-data)
(import/employer-taxes "2023-12-29" "December 2023" "rt:19462/674660" grouped-data)
(import/payroll-fees "2023-12-29" "December 2023" "rt:19459/675387" "rt:19459/674887" 206.50M grouped-data)
(import/retirement "2024-01-02" "December 2023" "rt:19403/676724" "rt:19403/675431" grouped-data))]
(t/is (= (count imported) 6))))
(comment
(t/run-all-tests)
)