diff --git a/README.md b/README.md index da61be6..842d6a9 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,18 @@ # 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. +This tool automates the monthly task of transcribing a payroll CSV from service +provider Paychex into around 300 lines of fairly intricate Beancount bookkeeping +data. ## Usage -See a demo with: +The run, the program requires a Java runtime (tested with OpenJDK 17 and 21). +On Debian 12 (Bookworm): + + sudo apt install openjdk-17-jre + +Run a demo with two example employees, Jack and Jill Citizen: java -jar import-x.x.x-standalone.jar --demo @@ -16,8 +21,8 @@ Provide your own payroll data with: java -jar import-x.x.x-standalone.jar --csv resources/example-paychex-pay-item-details.csv --total-fees 206.50 In the above, various values such as the date, time period covered and -receipt/invoice values will be replace with "TODO" placeholders. You can -alternatively provide any/all of these explicitly: +receipt/invoice values show "TODO" placeholders that you are expected to fill in +later. If you prefer, you can provide any/all of these explicitly: java -jar import-x.x.x-standalone.jar --csv resources/example-paychex-pay-item-details.csv --date 2023-12-29 --period 'December 2023' --total-fees 206.50 --pay-receipt-no rt:19462/674660 --pay-invoice-no rt:19403/675431 --fees-receipt-no rt:19459/675387 --fees-invoice-no rt:19459/674887 --retirement-receipt-no rt:19403/676724 --retirement-invoice-no rt:19403/675431 @@ -37,6 +42,21 @@ Then run Beancount with: bean-report [your file] balances +## Building + +To build you need a Java SDK (tested with OpenJDK 17 and 21) and Clojure. On +Debian 12 (Bookworm): + + sudo apt install openjdk-17-jdk clojure + +To build, run: + + bin/build + +This will output a JAR file like `target/import-x.x.x-standalone.jar`, where the +version number is based on the Git revision. + + ## Development Run tests with: @@ -51,10 +71,15 @@ The project is set up for development in Emacs and CIDER-mode. Open a source file and run `cider-jack-in`. -## Build +## Why Clojure? -To build, run: - - bin/build - -This will output a JAR file like `target/import-x.x.x-standalone.jar`. +Clojure is very well-suited to this kind of data +transformation/manipulation. Even without fully understanding the implications +of all the accounting/tax concepts I was able to parse the previous +human-generated Beancount entries into a data structure and work backwards to +produce results that matched exactly, without worrying about exact text +formatting. Libraries like deep-diff2 and the editor-integrated REPL made it +very efficient to compare the data structures and build the program - certainly +much more efficient than developing the same program in Python. It's only just +over 500 lines of code and we've had zero bugs as of writing (one year since it +was built). diff --git a/TODO.md b/TODO.md index 7bf01f7..cd2148d 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,5 @@ # To-do -* Validation/error handling on CLI arguments - required options like csv, date, period +* Add validation/error handling of required CLI arguments such as csv, date and period * Potentially move employee-name->entity-tag into config * Potentially move cat->payroll-type into config diff --git a/bin/build b/bin/build index a16f8ef..21d40ce 100755 --- a/bin/build +++ b/bin/build @@ -1,2 +1,4 @@ #!/usr/bin/env sh + +# Build an uberjar (a Java jar package including the program and all dependencies) clojure -T:build uber diff --git a/bin/dev b/bin/dev index 9d984aa..cd7dc20 100755 --- a/bin/dev +++ b/bin/dev @@ -1,2 +1,4 @@ #!/usr/bin/env sh + +# Run the program without building it clojure -M -m core "$@" diff --git a/bin/loc b/bin/loc new file mode 100755 index 0000000..b6df469 --- /dev/null +++ b/bin/loc @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +# Count the lines of code, excluding tests and examples +git ls-files -- \ + ':!:LICENSE.txt' \ + ':!:test/*' \ + ':!:resources/example-*.csv' \ + | xargs cloc "$@" diff --git a/bin/test b/bin/test index af4849e..6eeaf1d 100755 --- a/bin/test +++ b/bin/test @@ -1,2 +1,4 @@ #!/usr/bin/env sh + +# Run the test suite clojure -M:test "$@" diff --git a/manifest.scm b/manifest.scm new file mode 100644 index 0000000..e258fa9 --- /dev/null +++ b/manifest.scm @@ -0,0 +1,12 @@ +;; Guix manifest +;; +;; If you're running GNU Guix, this file describes the dependencies necessary to +;; develop/build the program. Use it with `guix shell --manifest=manifest.scm`. +(specifications->manifest + (list + ;; No issues running this OpenJDK 21 program on Debian Stable (OpenJDK 17). + "openjdk@21" + ;; Works fine with clojure-tools from Guix. + "clojure-tools" + "beancount" + ))