Add example data and test, fix ungrouping, extend docs
This commit is contained in:
parent
b4b42b72aa
commit
47cabfb0a9
5 changed files with 82 additions and 4 deletions
|
@ -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
|
||||
|
|
5
deps.edn
5
deps.edn
|
@ -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}}}
|
||||
|
|
28
resources/example-paychex-pay-item-details.csv
Normal file
28
resources/example-paychex-pay-item-details.csv
Normal 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,,,
|
|
|
@ -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
19
test/import_test.clj
Normal 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)
|
||||
)
|
Loading…
Reference in a new issue