diff --git a/src/clj/auto_ap/ssr/account.clj b/src/clj/auto_ap/ssr/account.clj index 4a63a128..769afad3 100644 --- a/src/clj/auto_ap/ssr/account.clj +++ b/src/clj/auto_ap/ssr/account.clj @@ -9,7 +9,8 @@ :refer [entity-id ref->enum-schema wrap-schema-enforce]] [com.brunobonacci.mulog :as mu] [datomic.api :as dc] - [ring.middleware.json :refer [wrap-json-response]])) + [ring.middleware.json :refer [wrap-json-response]] + [auto-ap.datomic.accounts :as d-accounts])) ;; TODO this is basically duplicative of graphql version, make sure to keep in sync ;; TODO use valid clients from request rather than stuff like assert-can-see-client @@ -17,9 +18,13 @@ (def search-pattern [:db/id :account/numeric-code :account/location + :account/name {:account/vendor-allowance [:db/ident] :account/default-allowance [:db/ident] - :account/invoice-allowance [:db/ident]}]) + :account/invoice-allowance [:db/ident] + :account/client-overrides [:db/id + :account-client-override/name + {:account-client-override/client [:db/id :client/name]}]} ]) (defn search- [id query client] (let [client-part (if (some->> client (can-see-client? id)) @@ -67,7 +72,9 @@ (valid-allowances (-> a allowance :db/ident)) (= (:db/id a) vendor-account)))) (map (fn [[n a]] - {:label (str (:account/numeric-code a) " - " n) + {:label (str (:account/numeric-code a) " - " (if client-id + (:account/name (d-accounts/clientize a client-id)) + n)) :value (:db/id a) :location (:account/location a) :warning (when (= :allowance/warn (-> a allowance :db/ident)) diff --git a/src/clj/auto_ap/ssr/ledger/new.clj b/src/clj/auto_ap/ssr/ledger/new.clj index b089d72f..27771386 100644 --- a/src/clj/auto_ap/ssr/ledger/new.clj +++ b/src/clj/auto_ap/ssr/ledger/new.clj @@ -17,15 +17,16 @@ [auto-ap.ssr.svg :as svg] [auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers check-allowance check-location-belongs clj-date-schema entity-id - html-response modal-response money - wrap-form-4xx-2 wrap-schema-enforce]] + html-response main-transformer modal-response + money wrap-form-4xx-2 wrap-schema-enforce]] [auto-ap.time :as atime] [bidi.bidi :as bidi] [clj-time.coerce :as coerce] [clojure.string :as str] [datomic.api :as dc] [iol-ion.query :refer [dollars=]] - [iol-ion.utils :refer [remove-nils]]) + [iol-ion.utils :refer [remove-nils]] + [malli.core :as m]) (:import [java.util UUID])) @@ -33,20 +34,20 @@ [:and [:map [:db/id {:optional true} [:maybe entity-id]] - [:journal-entry/client [:entity-map {:pull [:db/id :client/name :client/locations]}]] + [:journal-entry/client {:optional false} [:entity-map {:pull [:db/id :client/name :client/locations] }]] [:journal-entry/date clj-date-schema] - [:journal-entry/vendor {:optional true :default nil} - [:entity-map {:pull [:db/id :vendor/name]}]] + [:journal-entry/vendor {:optional false :default nil} + [:entity-map {:pull [:db/id :vendor/name] }]] [:journal-entry/amount {:min 0.01} money] [:journal-entry/line-items [:vector {:coerce? true} [:and [:map - [:journal-entry-line/account [:and [:entity-map {:pull a/default-read}] + [:journal-entry-line/account [:and [:entity-map {:pull a/default-read }] [:fn {:error/message "Not an allowed account."} (fn check-allow [x] - (check-allowance x :account/default-allowance))]]] + (check-allowance (:db/id x) :account/default-allowance))]]] [:journal-entry-line/debit {:optional true :default nil} [:maybe money]] [:journal-entry-line/credit {:optional true :default nil} [:maybe money]] [:journal-entry-line/location :string]] @@ -69,7 +70,6 @@ (map :journal-entry-line/credit) (filter identity) (reduce + 0.0)))))]]) - (defn- account-typeahead* [{:keys [name value client-id x-model]}] [:div.flex.flex-col @@ -92,7 +92,7 @@ (com/select {:options (into [["" ""]] (cond account-location [[account-location account-location]] - + :else (for [c (seq client-locations)] [c c]))) @@ -109,7 +109,7 @@ (pull-attr (dc/db conn) :client/locations))}))) (defn- line-item-row* - [account client-id client-locations] + [account client client-locations] (com/data-grid-row (-> {:x-data (hx/json {:accountId (or (:db/id (fc/field-value (:journal-entry-line/account account))) (fc/field-value (:journal-entry-line/account account))) @@ -134,7 +134,7 @@ :hx-get (str (bidi/path-for ssr-routes/only-routes ::route/account-typeahead)) :x-init "$watch('clientId', cid => $dispatch('changed', $data));"}] (account-typeahead* {:value (fc/field-value) - :client-id client-id + :client-id (:db/id client) :name (fc/field-name) :x-model "accountId"})))) (fc/with-field :journal-entry-line/location @@ -149,9 +149,10 @@ :hx-swap "outerHTML" :hx-vals (format "js:{name: '%s', 'client-id': event.detail.clientId || '', 'account-id': event.detail.accountId || '', value: event.detail.location || ''}" (fc/field-name)) :hx-get (bidi/path-for ssr-routes/only-routes ::route/location-select) - :x-init "$watch('clientId', cid => $dispatch('changed', $data)); $watch('accountId', cid => $dispatch('changed', $data) )"}] + :x-dispatch:changed "[clientId, accountId]" + #_#_:x-init "$watch('clientId', cid => $dispatch('changed', $data)); $watch('accountId', cid => $dispatch('changed', $data) )"}] (location-select* {:name (fc/field-name) - :account-location (:account/location (:account/location (:journal-entry-line/account @account))) + :account-location (:account/location (:journal-entry-line/account @account)) :client-locations client-locations :x-model "location" :value (fc/field-value)})))) @@ -176,8 +177,8 @@ (defn account-typeahead [{{:keys [name value client-id] :as qp} :query-params}] (html-response (account-typeahead* {:name name - :value value - :client-id client-id + :value (dc/pull (dc/db conn) a/default-read value) + :client-id client-id :x-model "accountId"}))) (defn form* [request] @@ -260,7 +261,6 @@ (defn new [request] - (alog/peek ::FP (:form-params request)) (modal-response (com/modal {:hx-target "this" :hx-indicator "this"} diff --git a/src/clj/auto_ap/ssr/utils.clj b/src/clj/auto_ap/ssr/utils.clj index 2a8b6e25..d2b7bf52 100644 --- a/src/clj/auto_ap/ssr/utils.clj +++ b/src/clj/auto_ap/ssr/utils.clj @@ -285,7 +285,7 @@ (def pull-transformer (mt2/transformer {:decoders {:entity-map - {:compile (fn [schema _] + {:compile (fn [schema g] (let [pull-expr (:pull (mc/properties schema))] (if pull-expr (fn pull-data [m] @@ -469,7 +469,14 @@ main-transformer))) (catch Exception e - (alog/warn ::validation-error :error e) + (alog/warn ::validation-error + :error e + ::errors (-> e + (ex-data) + :data + :explain + (me/humanize {:errors (assoc me/default-errors + ::mc/missing-key {:error/message {:en "required"}})}))) (throw (ex-info (->> (-> e (ex-data) :data @@ -643,7 +650,8 @@ {:entity-id entity-id :entity-map (mc/-simple-schema {:type :entity-map - :pred map?}) + :pred map? + :type-properties { :error/message "required"}}) #_[:map {:name :entity-map} [:db/id nat-int?]]})) (comment @@ -666,15 +674,21 @@ (handler (update-in request [:route-params] merge route-params)))) (defn check-allowance [account-id allowance-key] - (let [allowance (allowance-key (dc/pull (dc/db conn) '[{[:account/invoice-allowance :xform iol-ion.query/ident] [:db/ident] + (let [account-id (if (map? account-id) + (:db/id account-id) + account-id) + allowance (allowance-key (dc/pull (dc/db conn) '[{[:account/invoice-allowance :xform iol-ion.query/ident] [:db/ident] [:account/vendor-allowance :xform iol-ion.query/ident] [:db/ident] [:account/default-allowance :xform iol-ion.query/ident] [:db/ident]}] account-id))] (not= :allowance/denied allowance))) -(defn check-location-belongs [location account] - (let [account-location (pull-attr (dc/db conn) :account/location account)] +(defn check-location-belongs [location account-id] + (let [account (if (map? account-id) + (:db/id account-id) + account-id) + account-location (pull-attr (dc/db conn) :account/location account)] (when (and (seq account-location) (not= location account-location))