(ns auto-ap.integration.graphql.invoices (:require [auto-ap.time-reader] [auto-ap.datomic :refer [conn]] [auto-ap.graphql.invoices :as sut] [clojure.test :as t :refer [deftest is testing use-fixtures]] [auto-ap.integration.util :refer [admin-token setup-test-data test-account test-invoice test-vendor wrap-setup]] [datomic.api :as d])) (use-fixtures :each wrap-setup) (deftest test-add-invoice (testing "It should Add an invoice" (let [{:strs [test-vendor-id test-client-id test-account-id denied-account-id vendor-account-id vendor-with-special-account]} (setup-test-data [(test-account :db/id "denied-account-id" :account/invoice-allowance :allowance/denied) (test-account :db/id "vendor-account-id" :account/invoice-allowance :allowance/denied :account/vendor-allowance :allowance/allowed) (test-vendor :db/id "vendor-with-special-account" :vendor/default-account "vendor-account-id")])] (is (some? (sut/add-invoice {:id (admin-token)} {:invoice {:client_id test-client-id :vendor_id test-vendor-id :invoice_number "123" :date #clj-time/date-time "2022-01-01" :total 10.00 :expense_accounts [{:amount 10.0 :location "DT" :account_id test-account-id}]}} nil))) (testing "It should prevent an expense account that isn't allowed" (is (thrown? Exception (sut/add-invoice {:id (admin-token)} {:invoice {:client_id test-client-id :vendor_id test-vendor-id :invoice_number "789" :date #clj-time/date-time "2022-01-01" :total 10.00 :expense_accounts [{:amount 10.0 :location "DT" :account_id denied-account-id}]}} nil)))) (testing "It should allow an expense account that is valid for the vendor" (is (some? (sut/add-invoice {:id (admin-token)} {:invoice {:client_id test-client-id :vendor_id vendor-with-special-account :invoice_number "456" :date #clj-time/date-time "2022-01-01" :total 10.00 :expense_accounts [{:amount 10.0 :location "DT" :account_id vendor-account-id}]}} nil))))))) (deftest edit-invoice (testing "It should edit invoices" (let [{:strs [invoice-id new-vendor-id new-account-id]} (setup-test-data [(test-invoice :db/id "invoice-id") (test-vendor :db/id "new-vendor-id") (test-account :db/id "new-account-id")])] (is (some? (sut/edit-invoice {:id (admin-token)} {:invoice {:id invoice-id :vendor_id new-vendor-id :invoice_number "890213" :date #clj-time/date-time "2023-01-01" :total 100.00 :outstanding_balance 100.00 :expense_accounts [{:amount 100.0 :location "DT" :account_id new-account-id}]}} nil))) (is (= #:invoice{:invoice-number "890213" :date #inst "2023-01-01T00:00:00.000-00:00" :total 100.0 :expense-accounts [#:invoice-expense-account{:amount 100.0 :location "DT" :account {:db/id new-account-id}}]} (d/pull (d/db conn) [:invoice/invoice-number :invoice/date :invoice/total {:invoice/expense-accounts [:invoice-expense-account/amount :invoice-expense-account/location :invoice-expense-account/account]}] invoice-id))) (testing "Should not be able to change vendor" (is (not= new-vendor-id (:db/id (:invoice/vendor (d/pull (d/db conn) [:invoice/vendor] invoice-id)))))))) (testing "Should disallow adding a conflicting invoice" (let [{:strs [invoice-id]} (setup-test-data [(test-invoice :db/id "invoice-id" :invoice/invoice-number "original-invoice" :invoice/vendor "test-vendor-id" :invoice/client "test-client-id") (test-invoice :db/id "extant-invoice-id" :invoice/invoice-number "already taken" :invoice/vendor "test-vendor-id" :invoice/client "test-client-id")])] (is (thrown? Exception (sut/edit-invoice {:id (admin-token)} {:invoice {:id invoice-id :invoice_number "already taken"}} nil)))))) (deftest edit-expense-accounts (testing "It should edit expense accounts" (let [{:strs [invoice-id new-account-id]} (setup-test-data [(test-invoice :db/id "invoice-id") (test-account :db/id "new-account-id")])] (is (some? (sut/edit-expense-accounts {:id (admin-token)} {:invoice_id invoice-id :expense_accounts [{:amount 100.0 :account_id new-account-id :location "DT"}]} nil))) (is (= [#:invoice-expense-account{:amount 100.0 :location "DT" :account {:db/id new-account-id}}] (-> (d/pull (d/db conn) [{:invoice/expense-accounts [:invoice-expense-account/amount :invoice-expense-account/location :invoice-expense-account/account]}] invoice-id) :invoice/expense-accounts)))))) (deftest bulk-change-invoices (testing "It should change expense accounts in bulk" (let [{:strs [invoice-id new-account-id test-client-id]} (setup-test-data [(test-invoice :db/id "invoice-id") (test-account :db/id "new-account-id")])] (is (some? (sut/bulk-change-invoices {:id (admin-token)} {:client_id test-client-id :filters {:client_id test-client-id} :accounts [{:percentage 1.0 :account_id new-account-id :location "Shared"}]} nil))) (is (= [#:invoice-expense-account{:amount 100.0 :location "DT" :account {:db/id new-account-id}}] (-> (d/pull (d/db conn) [{:invoice/expense-accounts [:invoice-expense-account/amount :invoice-expense-account/location :invoice-expense-account/account]}] invoice-id) :invoice/expense-accounts)))))) (deftest void-invoices (testing "It should voide invoices in bulk" (let [{:strs [invoice-id test-client-id]} (setup-test-data [(test-invoice :db/id "invoice-id" :invoice/status :invoice-status/unpaid) (test-account :db/id "new-account-id")])] (is (some? (sut/void-invoices {:id (admin-token)} {:filters {:client_id test-client-id}} nil))) (is (= :invoice-status/voided (-> (d/pull (d/db conn) [{:invoice/status [:db/ident]}] invoice-id) :invoice/status :db/ident))) (testing "Should unvoid invoice" (is (some? (sut/unvoid-invoice {:id (admin-token)} {:invoice_id invoice-id} nil))) (is (= :invoice-status/unpaid (-> (d/pull (d/db conn) [{:invoice/status [:db/ident]}] invoice-id) :invoice/status :db/ident))))))) (deftest void-invoice (testing "It should voide invoices in bulk" (let [{:strs [invoice-id]} (setup-test-data [(test-invoice :db/id "invoice-id" :invoice/status :invoice-status/unpaid) (test-account :db/id "new-account-id")])] (is (some? (sut/void-invoice {:id (admin-token)} {:invoice_id invoice-id} nil))) (is (= :invoice-status/voided (-> (d/pull (d/db conn) [{:invoice/status [:db/ident]}] invoice-id) :invoice/status :db/ident))) (testing "Should unvoid invoice" (is (some? (sut/unvoid-invoice {:id (admin-token)} {:invoice_id invoice-id} nil))) (is (= :invoice-status/unpaid (-> (d/pull (d/db conn) [{:invoice/status [:db/ident]}] invoice-id) :invoice/status :db/ident)))))))