makes sure rounding happens.
This commit is contained in:
@@ -95,28 +95,40 @@
|
|||||||
(filter #(rule-applies? transaction %))))
|
(filter #(rule-applies? transaction %))))
|
||||||
|
|
||||||
(defn apply-rule [transaction rule valid-locations]
|
(defn apply-rule [transaction rule valid-locations]
|
||||||
(assoc transaction
|
(with-precision 2
|
||||||
:transaction/matched-rule (:db/id rule)
|
(let [accounts (vec (mapcat
|
||||||
:transaction/approval-status (:transaction-rule/transaction-approval-status rule)
|
(fn [tra]
|
||||||
:transaction/accounts (mapcat
|
(if (= "Shared" (:transaction-rule-account/location tra))
|
||||||
(fn [tra]
|
(map
|
||||||
(if (= "Shared" (:transaction-rule-account/location tra))
|
(fn [location]
|
||||||
(map
|
{:transaction-account/account (:db/id (:transaction-rule-account/account tra))
|
||||||
(fn [location]
|
:transaction-account/amount (Math/abs (* (/ 1.0 (count valid-locations))
|
||||||
{:transaction-account/account (:db/id (:transaction-rule-account/account tra))
|
(:transaction-rule-account/percentage tra)
|
||||||
:transaction-account/amount (Math/abs (* (/ 1.0 (count valid-locations))
|
(:transaction/amount transaction)))
|
||||||
(:transaction-rule-account/percentage tra)
|
:transaction-account/location location})
|
||||||
(:transaction/amount transaction)))
|
|
||||||
:transaction-account/location location})
|
|
||||||
|
|
||||||
|
|
||||||
valid-locations)
|
valid-locations)
|
||||||
[{:transaction-account/account (:db/id (:transaction-rule-account/account tra))
|
[{:transaction-account/account (:db/id (:transaction-rule-account/account tra))
|
||||||
:transaction-account/amount (Math/abs (* (:transaction-rule-account/percentage tra)
|
:transaction-account/amount (Math/abs (* (:transaction-rule-account/percentage tra)
|
||||||
(:transaction/amount transaction)))
|
(:transaction/amount transaction)))
|
||||||
:transaction-account/location (:transaction-rule-account/location tra)}]))
|
:transaction-account/location (:transaction-rule-account/location tra)}]))
|
||||||
(:transaction-rule/accounts rule))
|
(:transaction-rule/accounts rule)))
|
||||||
:transaction/vendor (:db/id (:transaction-rule/vendor rule))))
|
accounts (mapv
|
||||||
|
(fn [a]
|
||||||
|
(update a :transaction-account/amount
|
||||||
|
#(with-precision 2
|
||||||
|
(double (.setScale (bigdec %) 2 java.math.RoundingMode/HALF_UP)))))
|
||||||
|
accounts)
|
||||||
|
leftover (with-precision 2 (.round (bigdec (- (Math/abs (:transaction/amount transaction))
|
||||||
|
(Math/abs (reduce + 0.0 (map #(:transaction-account/amount %) accounts)))))
|
||||||
|
*math-context*))
|
||||||
|
accounts (update-in accounts [(dec (count accounts)) :transaction-account/amount] #(+ % (double leftover)))]
|
||||||
|
(assoc transaction
|
||||||
|
:transaction/matched-rule (:db/id rule)
|
||||||
|
:transaction/approval-status (:transaction-rule/transaction-approval-status rule)
|
||||||
|
:transaction/accounts accounts
|
||||||
|
:transaction/vendor (:db/id (:transaction-rule/vendor rule))))))
|
||||||
|
|
||||||
(defn rule-applying-fn [rules]
|
(defn rule-applying-fn [rules]
|
||||||
(let [rules-by-priority (group-rules-by-priority rules)]
|
(let [rules-by-priority (group-rules-by-priority rules)]
|
||||||
|
|||||||
@@ -211,7 +211,7 @@
|
|||||||
|
|
||||||
(deftest test-match-transaction-rule
|
(deftest test-match-transaction-rule
|
||||||
(testing "it should apply a rules"
|
(testing "it should apply a rules"
|
||||||
(let [{:strs [transaction-id transaction-rule-id]} (-> @(d/transact (d/connect uri)
|
(let [{:strs [transaction-id transaction-rule-id uneven-transaction-rule-id]} (-> @(d/transact (d/connect uri)
|
||||||
[{:transaction/description-original "matching-desc"
|
[{:transaction/description-original "matching-desc"
|
||||||
:transaction/date #inst "2019-01-05T00:00:00.000-08:00"
|
:transaction/date #inst "2019-01-05T00:00:00.000-08:00"
|
||||||
:transaction/client {:client/name "1"
|
:transaction/client {:client/name "1"
|
||||||
@@ -226,29 +226,55 @@
|
|||||||
:transaction-rule/description "matching-desc"
|
:transaction-rule/description "matching-desc"
|
||||||
:transaction-rule/accounts [{:transaction-rule-account/location "A"
|
:transaction-rule/accounts [{:transaction-rule-account/location "A"
|
||||||
:transaction-rule-account/account {:account/numeric-code 123 :db/id "123"}
|
:transaction-rule-account/account {:account/numeric-code 123 :db/id "123"}
|
||||||
:transaction-rule-account/percentage 1.0}]}])
|
:transaction-rule-account/percentage 1.0}]}
|
||||||
|
{:db/id "uneven-transaction-rule-id"
|
||||||
|
:transaction-rule/note "transaction rule note"
|
||||||
|
:transaction-rule/description "matching-desc"
|
||||||
|
:transaction-rule/accounts [{:transaction-rule-account/location "A"
|
||||||
|
:transaction-rule-account/account {:account/numeric-code 123 :db/id "123"}
|
||||||
|
:transaction-rule-account/percentage 0.3333333}
|
||||||
|
{:transaction-rule-account/location "B"
|
||||||
|
:transaction-rule-account/account {:account/numeric-code 123 :db/id "123"}
|
||||||
|
:transaction-rule-account/percentage 0.33333333}
|
||||||
|
{:transaction-rule-account/location "c"
|
||||||
|
:transaction-rule-account/account {:account/numeric-code 123 :db/id "123"}
|
||||||
|
:transaction-rule-account/percentage 0.333333}]}])
|
||||||
:tempids)
|
:tempids)
|
||||||
rule-test (-> (sut/query (admin-token) (v/graphql-query {:venia/operation {:operation/type :mutation
|
rule-test (-> (sut/query (admin-token) (v/graphql-query {:venia/operation {:operation/type :mutation
|
||||||
:operation/name "MatchTransactionRule"}
|
:operation/name "MatchTransactionRules"}
|
||||||
:venia/queries [{:query/data (sut/->graphql [:match-transaction-rule
|
:venia/queries [{:query/data (sut/->graphql [:match-transaction-rules
|
||||||
{:transaction-rule-id transaction-rule-id
|
{:transaction-rule-id transaction-rule-id
|
||||||
:transaction-id transaction-id}
|
:transaction-ids [transaction-id]}
|
||||||
[[:matched-rule [:id :note]] [:accounts [:id]] ]])}]}))
|
[[:matched-rule [:id :note]] [:accounts [:id]] ]])}]}))
|
||||||
:data
|
:data
|
||||||
:match-transaction-rule)]
|
:match-transaction-rules)]
|
||||||
|
|
||||||
(is (= "transaction rule note" (-> rule-test :matched-rule :note)))
|
(is (= "transaction rule note" (-> rule-test first :matched-rule :note)))
|
||||||
(is (= 1 (-> rule-test :accounts count)))
|
(is (= 1 (-> rule-test first :accounts count)))
|
||||||
|
|
||||||
(testing "Should replace accounts when matching a second time"
|
(testing "Should replace accounts when matching a second time"
|
||||||
(let [rule-test (-> (sut/query (admin-token) (v/graphql-query {:venia/operation {:operation/type :mutation
|
(let [rule-test (-> (sut/query (admin-token) (v/graphql-query {:venia/operation {:operation/type :mutation
|
||||||
:operation/name "MatchTransactionRule"}
|
:operation/name "MatchTransactionRules"}
|
||||||
:venia/queries [{:query/data (sut/->graphql [:match-transaction-rule
|
:venia/queries [{:query/data (sut/->graphql [:match-transaction-rules
|
||||||
{:transaction-rule-id transaction-rule-id
|
{:transaction-rule-id transaction-rule-id
|
||||||
:transaction-id transaction-id}
|
:transaction-ids [transaction-id]}
|
||||||
[[:matched-rule [:id :note]] [:accounts [:id]] ]])}]}))
|
[[:matched-rule [:id :note]] [:accounts [:id]] ]])}]}))
|
||||||
:data
|
:data
|
||||||
:match-transaction-rule)]
|
:match-transaction-rules)]
|
||||||
(is (= 1 (-> rule-test :accounts count))))))))
|
(is (= 1 (-> rule-test first :accounts count)))))
|
||||||
|
|
||||||
|
(testing "Should round when the transaction can't be divided eventy"
|
||||||
|
(let [rule-test (-> (sut/query (admin-token) (v/graphql-query {:venia/operation {:operation/type :mutation
|
||||||
|
:operation/name "MatchTransactionRules"}
|
||||||
|
:venia/queries [{:query/data (sut/->graphql [:match-transaction-rules
|
||||||
|
{:transaction-rule-id uneven-transaction-rule-id
|
||||||
|
:transaction-ids [transaction-id]}
|
||||||
|
[[:matched-rule [:id :note]] [:accounts [:id :amount]] ]])}]}))
|
||||||
|
:data
|
||||||
|
:match-transaction-rules)]
|
||||||
|
(is (= 3 (-> rule-test first :accounts count)))
|
||||||
|
(is (= "0.33" (-> rule-test first :accounts (nth 0) :amount)))
|
||||||
|
(is (= "0.33" (-> rule-test first :accounts (nth 1) :amount)))
|
||||||
|
(is (= "0.34" (-> rule-test first :accounts (nth 2) :amount))))))))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user