diff --git a/resources/example-paychex-pay-item-details.csv b/resources/example-paychex-pay-item-details-2024.csv similarity index 100% rename from resources/example-paychex-pay-item-details.csv rename to resources/example-paychex-pay-item-details-2024.csv diff --git a/resources/example-paychex-pay-item-details-2025.csv b/resources/example-paychex-pay-item-details-2025.csv new file mode 100644 index 0000000..df04b2c --- /dev/null +++ b/resources/example-paychex-pay-item-details-2025.csv @@ -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 Expense,,,,,,,,,0,, +Example Co Inc,"Citizen, Jack A",1,Medicare,Withholding,,,,,,,,88,,, +Example Co Inc,"Citizen, Jack A",1,Medicare,Liability Expense,,,,,,,,,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 Expense,,,,,,,,,376.28,, +Example Co Inc,"Citizen, Jack A",1,TN Unemploy,Liability Expense,,,,,,,,,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 Expense,,,,,,,,,0,, +Example Co Inc,"Citizen, Jill B",2,Medicare,Liability Expense,,,,,,,,,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 Expense,,,,,,,,,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 Expense,,,,,,,,,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 Expense,,,,,,,,,0,, +Example Co Inc,"Citizen, Jill B",2,Salary,Earnings,6847.12,,0,,,,,,,, +Example Co Inc,"Citizen, Jill B",2,Social Security,Liability Expense,,,,,,,,,424.52,, +Example Co Inc,"Citizen, Jill B",2,Social Security,Withholding,,,,,,,,424.52,,, diff --git a/src/import.clj b/src/import.clj index 23ebf94..d760f8a 100644 --- a/src/import.clj +++ b/src/import.clj @@ -228,7 +228,8 @@ :approval "Financial/Employment-Records/memo-re-board-approval-of-payroll.txt"} :postings []} liability-records (filter (fn [{:keys [category type]}] - (and (= type "Liability") + ;; CSV originally used "Liability", but changed to "Liability Expe + (and (contains? #{"Liability" "Liability Expense"} type) (not (str/includes? category "Unemploy")))) records) liability-postings (for [{:keys [amount name category]} liability-records] {:account "Expenses:Payroll:Tax" @@ -242,7 +243,7 @@ :payroll-type (str/replace (cat->payroll-type category) "Tax:" "")})}) total-liabilities (total liability-records) unemploy-records (filter (fn [{:keys [category type]}] - (and (= type "Liability") + (and (contains? #{"Liability" "Liability Expense"} type) (str/includes? category "Unemploy"))) records) unemploy-postings (for [{:keys [amount name category]} unemploy-records] {:account "Expenses:Payroll:Tax" @@ -349,11 +350,11 @@ :approval "Financial/Employment-Records/memo-re-board-approval-of-payroll.txt"} :postings []} liability-records (filter (fn [{:keys [category type]}] - (and (= type "Liability") + (and (contains? #{"Liability" "Liability Expense"} type) (not (str/includes? category "Unemploy")))) records) total-liabilities (total liability-records) unemploy-records (filter (fn [{:keys [category type]}] - (and (= type "Liability") + (and (contains? #{"Liability" "Liability Expense"} type) (str/includes? category "Unemploy"))) records) total-unemploy (total unemploy-records) liability-postings [{:account "Liabilities:Payable:Accounts" diff --git a/test/import_test.clj b/test/import_test.clj index bc04462..1cd6670 100644 --- a/test/import_test.clj +++ b/test/import_test.clj @@ -5,12 +5,19 @@ (:require [import] [clojure.java.io] [clojure.string :as str] - [clojure.test :as t :refer [deftest is]])) + [clojure.test :as t :refer [deftest is are]])) + + +(def paychex-csv-2024 (->> "example-paychex-pay-item-details-2024.csv" + clojure.java.io/resource + import/read-csv)) + +(def paychex-csv-2025 (->> "example-paychex-pay-item-details-2025.csv" + clojure.java.io/resource + import/read-csv)) (deftest net-pay - (let [records (import/read-csv (clojure.java.io/resource "example-paychex-pay-item-details.csv")) - actual (import/net-pay "DATE" "PERIOD" "TODO-PAY-INVOICE" {} records) - expected '[{:date "DATE" + (let [expected '[{:date "DATE" :desc "Monthly Payroll - PERIOD - Net Pay" :meta {:program "Conservancy:Payroll" @@ -53,12 +60,12 @@ :amount -50M :currency "USD" :meta {:entity "Citizen-Jill" :tax-implication "Reimbursement"}})}]] - (is (= actual expected)))) + (are [records] (= expected (import/net-pay "DATE" "PERIOD" "TODO-PAY-INVOICE" {} records)) + paychex-csv-2024 + paychex-csv-2025))) (deftest individual-taxes - (let [records (import/read-csv (clojure.java.io/resource "example-paychex-pay-item-details.csv")) - actual (import/individual-taxes "DATE" "PERIOD" "TODO-PAY-INVOICE" "TODO-RETIREMENT-INVOICE" {} records) - expected '({:date "DATE" + (let [expected '({:date "DATE" :desc "Monthly Payroll - PERIOD - TAXES - Citizen-Jack" :meta {:project "Conservancy" @@ -148,12 +155,12 @@ :currency "USD" :meta {:tax-implication "W2"}} {:account "Liabilities:Payable:Accounts" :amount 0M :currency "USD"})})] - (is (= actual expected)))) + (are [records] (= expected (import/individual-taxes "DATE" "PERIOD" "TODO-PAY-INVOICE" "TODO-RETIREMENT-INVOICE" {} records)) + paychex-csv-2024 + paychex-csv-2025))) (deftest employer-taxes - (let [records (import/read-csv (clojure.java.io/resource "example-paychex-pay-item-details.csv")) - actual (import/employer-taxes "DATE" "PERIOD" "TODO-PAY-INVOICE" {} records) - expected '[{:date "DATE" + (let [expected '[{:date "DATE" :desc "Monthly Payroll - PERIOD - TAXES - Employer" :meta {:program "Conservancy:Payroll" @@ -219,14 +226,14 @@ :amount -988.08M :currency "USD" :meta {:entity "Paychex" :tax-implication "Tax-Payment"}})}]] - (is (= actual expected)))) + (are [records] (= expected (import/employer-taxes "DATE" "PERIOD" "TODO-PAY-INVOICE" {} records)) + paychex-csv-2024 + paychex-csv-2025))) ;; TODO: Add 2 x ACH credit tests (deftest fees - (let [records (import/read-csv (clojure.java.io/resource "example-paychex-pay-item-details.csv")) - actual (import/fees "DATE" "PERIOD" "TODO-FEES-RECEIPT" "TODO-FEES-INVOICE" 206.51 {} records) - expected '[{:date "DATE" + (let [expected '[{:date "DATE" :payee "Paychex" :desc "Monthly Payroll - PERIOD - Fee" :meta @@ -247,12 +254,12 @@ :currency "USD" :meta {:entity "Citizen-Jill"}} {:account "Assets:Citizens:Check1273" :amount -206.51 :currency "USD"})}]] - (is (= actual expected)))) + (are [records] (= expected (import/fees "DATE" "PERIOD" "TODO-FEES-RECEIPT" "TODO-FEES-INVOICE" 206.51 {} records)) + paychex-csv-2024 + paychex-csv-2025))) (deftest retirement - (let [records (import/read-csv (clojure.java.io/resource "example-paychex-pay-item-details.csv")) - actual (import/retirement "DATE" "PERIOD" "TODO-RETIREMENT-RECEIPT" "TODO-RETIREMENT-INVOICE" records) - expected '[{:date "DATE" + (let [expected '[{:date "DATE" :desc "ASCENSUS TRUST RET PLAN - ACH DEBIT - Vanguard 403(b) - PERIOD" :meta @@ -273,12 +280,12 @@ :currency "USD" :meta {:entity "Citizen-Jill"}} {:account "Assets:Citizens:Check1273" :amount -1820M :currency "USD"})}]] - (is (= actual expected)))) + (are [records] (= expected (import/retirement "DATE" "PERIOD" "TODO-RETIREMENT-RECEIPT" "TODO-RETIREMENT-INVOICE" records)) + paychex-csv-2024 + paychex-csv-2025))) (deftest net-pay-ach-debit - (let [records (import/read-csv (clojure.java.io/resource "example-paychex-pay-item-details.csv")) - actual (import/net-pay-ach-debit "DATE" "PERIOD" "TODO-PAY-RECEIPT" "TODO-PAY-INVOICE" {} records) - expected [{:date "DATE" + (let [expected [{:date "DATE" :desc "Monthly Payroll - PERIOD - Net Pay - ACH debit" :meta {:approval "Financial/Employment-Records/memo-re-board-approval-of-payroll.txt" :invoice "TODO-PAY-INVOICE" @@ -311,12 +318,12 @@ :amount -100M :currency "USD" :meta {:entity "Paychex" :tax-implication "Reimbursement"}}]}]] - (is (= actual expected)))) + (are [records] (= expected (import/net-pay-ach-debit "DATE" "PERIOD" "TODO-PAY-RECEIPT" "TODO-PAY-INVOICE" {} records)) + paychex-csv-2024 + paychex-csv-2025))) (deftest taxes-ach-debit - (let [records (import/read-csv (clojure.java.io/resource "example-paychex-pay-item-details.csv")) - actual (import/taxes-ach-debit "DATE" "PERIOD" "TODO-PAY-RECEIPT" "TODO-PAY-INVOICE" {} records) - expected [{:date "DATE" + (let [expected [{:date "DATE" :desc "Monthly Payroll - PERIOD - TAXES - ACH debit" :meta {:approval "Financial/Employment-Records/memo-re-board-approval-of-payroll.txt" :invoice "TODO-PAY-INVOICE" @@ -347,7 +354,9 @@ :amount -3602.31M :currency "USD" :meta {:entity "Paychex" :tax-implication "Tax-Payment"}}]}]] - (is (= actual expected)))) + (are [records] (= expected (import/taxes-ach-debit "DATE" "PERIOD" "TODO-PAY-RECEIPT" "TODO-PAY-INVOICE" {} records)) + paychex-csv-2024 + paychex-csv-2025))) (deftest render-transaction (let [transaction '{:date "DATE"