create manual ledger experience
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -33,6 +33,10 @@
|
||||
[:span.items-center.bg-red-100.text-red-800.text-xs.font-medium.mb-2.p-1.rounded-full.inline-flex (hx/alpine-appear {:x-show "unexpectedError" :class "dark:bg-red-900 dark:text-red-300"})
|
||||
[:span {:class "w-2 h-2 mr-1 bg-red-500 rounded-full"}]
|
||||
[:span.px-2.py-0.5 "An unexpected error has occured. Integreat staff have been notified."]]
|
||||
(when (:error params )
|
||||
[:span.items-center.bg-red-100.text-red-800.text-xs.font-medium.mb-2.p-1.rounded-full.inline-flex { :class "dark:bg-red-900 dark:text-red-300"}
|
||||
[:span {:class "w-2 h-2 mr-1 bg-red-500 rounded-full"}]
|
||||
[:span.px-2.py-0.5 (:error params)]])
|
||||
[:div {:class "shrink-0"}
|
||||
footer]])]])
|
||||
|
||||
@@ -52,6 +56,7 @@
|
||||
(defn modal-footer- [params & children]
|
||||
[:div {:class "p-4 border-t"}
|
||||
[:span.items-center.bg-red-100.text-red-800.text-xs.font-medium.mb-2.p-1.rounded-full.inline-flex
|
||||
(hx/alpine-appear {:x-show "unexpectedError" :class "dark:bg-red-900 dark:text-red-300"})
|
||||
(hx/alpine-appear {:x-show "unexpectedError" :class "dark:bg-red-900 dark:text-red-300"})
|
||||
[:span {:class "w-2 h-2 bg-red-500 rounded-full"}]
|
||||
[:span.px-2.py-0.5 "An unexpected error has occured. Integreat staff have been notified."]]
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
(ns auto-ap.ssr.invoice.new-invoice-wizard
|
||||
(:require [auto-ap.datomic
|
||||
(:require
|
||||
[auto-ap.client-routes :as client-routes]
|
||||
[auto-ap.datomic
|
||||
:refer [audit-transact conn pull-attr]]
|
||||
[auto-ap.datomic.accounts :as d-accounts]
|
||||
[auto-ap.datomic.invoices :as d-invoices]
|
||||
[auto-ap.graphql.utils :refer [assert-can-see-client
|
||||
assert-not-locked exception->4xx]]
|
||||
[auto-ap.logging :as alog]
|
||||
[auto-ap.routes.invoice :as route]
|
||||
[auto-ap.routes.utils
|
||||
[auto-ap.datomic.accounts :as d-accounts]
|
||||
[auto-ap.datomic.invoices :as d-invoices]
|
||||
[auto-ap.graphql.utils :refer [assert-can-see-client assert-not-locked
|
||||
exception->4xx]]
|
||||
[auto-ap.logging :as alog]
|
||||
[auto-ap.routes.invoice :as route]
|
||||
[auto-ap.routes.utils
|
||||
:refer [wrap-client-redirect-unauthenticated]]
|
||||
[auto-ap.rule-matching :as rm]
|
||||
[auto-ap.client-routes :as client-routes]
|
||||
[auto-ap.solr :as solr]
|
||||
[auto-ap.ssr-routes :as ssr-routes]
|
||||
[auto-ap.ssr.common-handlers :refer [add-new-entity-handler]]
|
||||
[auto-ap.ssr.components :as com]
|
||||
[auto-ap.ssr.components.multi-modal :as mm]
|
||||
[auto-ap.ssr.form-cursor :as fc]
|
||||
[auto-ap.ssr.hx :as hx]
|
||||
[auto-ap.ssr.invoice.common :refer [default-read]]
|
||||
[auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]]
|
||||
[auto-ap.ssr.svg :as svg]
|
||||
[auto-ap.ssr.utils
|
||||
:refer [->db-id apply-middleware-to-all-handlers clj-date-schema
|
||||
entity-id form-validation-error html-response money strip
|
||||
[auto-ap.solr :as solr]
|
||||
[auto-ap.ssr-routes :as ssr-routes]
|
||||
[auto-ap.ssr.common-handlers :refer [add-new-entity-handler]]
|
||||
[auto-ap.ssr.components :as com]
|
||||
[auto-ap.ssr.components.multi-modal :as mm]
|
||||
[auto-ap.ssr.form-cursor :as fc]
|
||||
[auto-ap.ssr.hx :as hx]
|
||||
[auto-ap.ssr.invoice.common :refer [default-read]]
|
||||
[auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]]
|
||||
[auto-ap.ssr.svg :as svg]
|
||||
[auto-ap.ssr.utils
|
||||
:refer [->db-id apply-middleware-to-all-handlers check-allowance
|
||||
check-location-belongs clj-date-schema entity-id
|
||||
form-validation-error html-response money strip
|
||||
wrap-schema-enforce]]
|
||||
[auto-ap.time :as atime]
|
||||
[bidi.bidi :as bidi]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clj-time.core :as time]
|
||||
[datomic.api :as dc]
|
||||
[hiccup.util :as hu]
|
||||
[iol-ion.query :refer [dollars=]]
|
||||
[iol-ion.utils :refer [random-tempid]]
|
||||
[malli.core :as mc]
|
||||
[malli.util :as mut]))
|
||||
[auto-ap.time :as atime]
|
||||
[bidi.bidi :as bidi]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clj-time.core :as time]
|
||||
[datomic.api :as dc]
|
||||
[hiccup.util :as hu]
|
||||
[iol-ion.query :refer [dollars=]]
|
||||
[malli.core :as mc]
|
||||
[malli.util :as mut]))
|
||||
|
||||
(defn get-vendor [vendor-id]
|
||||
(dc/pull
|
||||
@@ -49,24 +49,9 @@
|
||||
[:vendor-terms-override/client :vendor-terms-override/terms]}]
|
||||
vendor-id))
|
||||
|
||||
(defn check-invoice-expense-account-location [iea]
|
||||
(let [account-location (pull-attr (dc/db conn) :account/location (:invoice-expense-account/account iea))]
|
||||
(when (and (seq account-location)
|
||||
(not= (:invoice-expense-account/location iea)
|
||||
account-location))
|
||||
(throw (ex-info "Exception." {:type (str "expected " account-location)})))
|
||||
(when (and (empty? account-location)
|
||||
(= "A" (:invoice-expense-account/location iea)))
|
||||
|
||||
(throw (ex-info "Exception." {:type "'A' not allowed"})))
|
||||
true))
|
||||
|
||||
(defn check-allowance [account-id]
|
||||
(let [allowance (:account/invoice-allowance (dc/pull (dc/db conn) '[{[:account/invoice-allowance :xform iol-ion.query/ident]
|
||||
[:db/ident]}]
|
||||
account-id))]
|
||||
(not= :allowance/denied
|
||||
allowance)))
|
||||
|
||||
|
||||
(defn check-vendor-default-account [vendor-id]
|
||||
(some? (:vendor/default-account (get-vendor vendor-id))))
|
||||
@@ -95,11 +80,14 @@
|
||||
[:map
|
||||
[:invoice-expense-account/account [:and entity-id
|
||||
[:fn {:error/message "Not an allowed account."}
|
||||
check-allowance]]]
|
||||
#(check-allowance % :account/invoice-allowance)]]]
|
||||
[:invoice-expense-account/location :string]
|
||||
[:invoice-expense-account/amount :double]]
|
||||
[:fn {:error/fn (fn [r x] (:type r))
|
||||
:error/path [:invoice-expense-account/location]} check-invoice-expense-account-location]]]]])
|
||||
:error/path [:invoice-expense-account/location]}
|
||||
(fn [iea]
|
||||
(check-location-belongs (:invoice-expense-account/location iea)
|
||||
(:invoice-expense-account/account iea)))]]]]])
|
||||
|
||||
(defn wrap-schema [s]
|
||||
[:and s
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
(:require
|
||||
[auto-ap.datomic :refer [conn pull-attr]]
|
||||
[auto-ap.datomic.accounts :as d-accounts]
|
||||
[auto-ap.datomic.accounts :as a]
|
||||
[auto-ap.logging :as alog]
|
||||
[auto-ap.permissions :refer [wrap-must]]
|
||||
[auto-ap.routes.ledger :as route]
|
||||
[auto-ap.routes.utils :refer [wrap-client-redirect-unauthenticated]]
|
||||
@@ -12,11 +14,57 @@
|
||||
[auto-ap.ssr.hx :as hx]
|
||||
[auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]]
|
||||
[auto-ap.ssr.svg :as svg]
|
||||
[auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers entity-id
|
||||
modal-response wrap-schema-enforce]]
|
||||
[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]]
|
||||
[auto-ap.time :as atime]
|
||||
[bidi.bidi :as bidi]
|
||||
[datomic.api :as dc]))
|
||||
[clojure.string :as str]
|
||||
[datomic.api :as dc]
|
||||
[iol-ion.query :refer [dollars=]])
|
||||
(:import [java.util UUID]))
|
||||
|
||||
(def new-ledger-schema
|
||||
[:and
|
||||
[:map
|
||||
[:db/id {:optional true} [:maybe entity-id]]
|
||||
[:journal-entry/client [: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/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}]
|
||||
[:fn {:error/message "Not an allowed account."}
|
||||
(fn check-allow [x]
|
||||
(check-allowance 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]]
|
||||
[:fn {:error/fn (fn [r x] (:type r))
|
||||
:error/path [:invoice-expense-account/location]}
|
||||
(fn [iea]
|
||||
(check-location-belongs (:journal-entry-line/location iea)
|
||||
(:journal-entry-line/account iea)))]]]]]
|
||||
|
||||
[:fn {:error/message "Debits and Credits must add up to amount"}
|
||||
(fn [je]
|
||||
(and
|
||||
(dollars= (:journal-entry/amount je) (->> je
|
||||
:journal-entry/line-items
|
||||
(map :journal-entry-line/debit)
|
||||
(filter identity)
|
||||
(reduce + 0.0)))
|
||||
(dollars= (:journal-entry/amount je) (->> je
|
||||
:journal-entry/line-items
|
||||
(map :journal-entry-line/credit)
|
||||
(filter identity)
|
||||
(reduce + 0.0)))))]])
|
||||
|
||||
(defn- account-typeahead*
|
||||
[{:keys [name value client-id x-model]}]
|
||||
@@ -28,47 +76,50 @@
|
||||
:x-model x-model
|
||||
:value value
|
||||
:content-fn (fn [value]
|
||||
(let [a (dc/pull (dc/db conn) d-accounts/default-read value)]
|
||||
(when value
|
||||
(when value
|
||||
(str
|
||||
(:account/numeric-code a)
|
||||
(:account/numeric-code value)
|
||||
" - "
|
||||
(:account/name (d-accounts/clientize a
|
||||
client-id))))))})])
|
||||
(:account/name (d-accounts/clientize value
|
||||
client-id)))))})])
|
||||
|
||||
(defn- location-select*
|
||||
[{:keys [name account-location client-locations value]}]
|
||||
(com/select {:options (into [["" ""]]
|
||||
(cond account-location
|
||||
[[account-location account-location]]
|
||||
|
||||
(seq client-locations)
|
||||
(into [["Shared" "Shared"]]
|
||||
(for [cl client-locations]
|
||||
[cl cl]))
|
||||
|
||||
:else
|
||||
[["Shared" "Shared"]]))
|
||||
(for [c (seq client-locations)]
|
||||
[c c])))
|
||||
:name name
|
||||
:value value
|
||||
:class "w-full"}))
|
||||
|
||||
(defn location-select [{{:keys [name account-id client-id value] :as qp} :query-params}]
|
||||
(html-response (location-select* {:name name
|
||||
:value value
|
||||
:account-location (some->> account-id
|
||||
(pull-attr (dc/db conn) :account/location))
|
||||
:client-locations (some->> client-id
|
||||
(pull-attr (dc/db conn) :client/locations))})))
|
||||
|
||||
(defn- line-item-row*
|
||||
[account client-id client-locations]
|
||||
(com/data-grid-row
|
||||
(-> {:x-data (hx/json {:accountId (or (:db/id (fc/field-value (:transaction-rule-account/account account)))
|
||||
(fc/field-value (:transaction-rule-account/account account)))
|
||||
:location (fc/field-value (:transaction-rule-account/location account))
|
||||
(-> {:x-data (hx/json {:accountId (or (:db/id (fc/field-value (:journal-entry-line/account account)))
|
||||
(fc/field-value (:journal-entry-line/account account)))
|
||||
:location (fc/field-value (:journal-entry-line/location account))
|
||||
:show (boolean (not (fc/field-value (:new? account))))})
|
||||
:data-key "show"
|
||||
:x-ref "p"}
|
||||
hx/alpine-mount-then-appear)
|
||||
(let [account-name (fc/field-name (:transaction-rule-account/account account))]
|
||||
(let [account-name (fc/field-name (:journal-entry-line/account account))]
|
||||
(list
|
||||
|
||||
(fc/with-field :db/id
|
||||
(com/hidden {:name (fc/field-name)
|
||||
:value (fc/field-value)}))
|
||||
(fc/with-field :transaction-rule-account/account
|
||||
(fc/with-field :journal-entry-line/account
|
||||
(com/data-grid-cell
|
||||
{}
|
||||
(com/validated-field
|
||||
@@ -82,7 +133,7 @@
|
||||
:client-id client-id
|
||||
:name (fc/field-name)
|
||||
:x-model "accountId"}))))
|
||||
(fc/with-field :transaction-rule-account/location
|
||||
(fc/with-field :journal-entry-line/location
|
||||
(com/data-grid-cell
|
||||
{}
|
||||
(com/validated-field
|
||||
@@ -96,119 +147,177 @@
|
||||
: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) )"}]
|
||||
(location-select* {:name (fc/field-name)
|
||||
:account-location (:account/location (cond->> (:transaction-rule-account/account @account)
|
||||
(nat-int? (:transaction-rule-account/account @account)) (dc/pull (dc/db conn)
|
||||
'[:account/location])))
|
||||
:account-location (:account/location (:account/location (:journal-entry-line/account @account)))
|
||||
:client-locations client-locations
|
||||
:x-model "location"
|
||||
:value (fc/field-value)}))))
|
||||
(fc/with-field :transaction-rule-account/percentage
|
||||
(fc/with-field :journal-entry-line/debit
|
||||
(com/data-grid-cell
|
||||
{}
|
||||
(com/validated-field
|
||||
{:errors (fc/field-errors)}
|
||||
(com/money-input {:name (fc/field-name)
|
||||
:class "w-16"
|
||||
:value (some-> (fc/field-value)
|
||||
(* 100)
|
||||
(long))}))))))
|
||||
:value (fc/field-value)}))))
|
||||
(fc/with-field :journal-entry-line/credit
|
||||
(com/data-grid-cell
|
||||
{}
|
||||
(com/validated-field
|
||||
{:errors (fc/field-errors)}
|
||||
(com/money-input {:name (fc/field-name)
|
||||
:class "w-16"
|
||||
:value (fc/field-value)}))))))
|
||||
(com/data-grid-cell {:class "align-top"}
|
||||
(com/a-icon-button {"@click.prevent.stop" "show=false; setTimeout(() => $refs.p.remove(), 500)"} svg/x))))
|
||||
|
||||
(defn account-typeahead [{{:keys [name value client-id] :as qp} :query-params}]
|
||||
(html-response (account-typeahead* {:name name
|
||||
:value value
|
||||
:client-id client-id
|
||||
:x-model "accountId"})))
|
||||
|
||||
(defn form* [request]
|
||||
(fc/start-form (:form-params request)
|
||||
(:form-errors request)
|
||||
[:div.flex.gap-4.flex-col
|
||||
(fc/with-field :journal-entry/client
|
||||
(com/validated-field
|
||||
{:label "Client"
|
||||
:errors (fc/field-errors)}
|
||||
[:div.w-96
|
||||
(com/typeahead {:name (fc/field-name)
|
||||
:error? (fc/error?)
|
||||
:class "w-96"
|
||||
:placeholder "Search..."
|
||||
:url (bidi/path-for ssr-routes/only-routes :company-search)
|
||||
:value (fc/field-value)
|
||||
:content-fn (fn [c] (pull-attr (dc/db conn) :client/name c))})]))
|
||||
(fc/with-field :invoice/date
|
||||
(com/validated-field
|
||||
{:label "Date"
|
||||
:errors (fc/field-errors)}
|
||||
[:div {:class "w-24"}
|
||||
(com/date-input {:value (some-> (fc/field-value)
|
||||
(atime/unparse-local atime/normal-date))
|
||||
:name (fc/field-name)
|
||||
:error? (fc/field-errors)
|
||||
:placeholder "1/1/2024"})]))
|
||||
(fc/with-field :journal-entry/vendor
|
||||
(com/validated-field
|
||||
{:label "Vendor"
|
||||
:errors (fc/field-errors)}
|
||||
[:div.w-96
|
||||
(com/typeahead {:name (fc/field-name)
|
||||
:error? (fc/error?)
|
||||
:disabled (boolean (-> request :multi-form-state :snapshot :db/id))
|
||||
:class "w-96"
|
||||
:placeholder "Search..."
|
||||
:url (bidi/path-for ssr-routes/only-routes :vendor-search)
|
||||
:value (fc/field-value)
|
||||
:content-fn (fn [c] (pull-attr (dc/db conn) :vendor/name c))})]))
|
||||
(fc/with-field :invoice/total
|
||||
(com/validated-field
|
||||
{:label "Total"
|
||||
:errors (fc/field-errors)}
|
||||
[:div {:class "w-16"}
|
||||
(com/money-input {:value (-> (fc/field-value))
|
||||
:name (fc/field-name)
|
||||
:class "w-24"
|
||||
:error? (fc/field-errors)
|
||||
:placeholder "212.44"})]))
|
||||
(fc/with-field :journal-entry/line-items
|
||||
(com/validated-field
|
||||
{:errors (fc/field-errors)}
|
||||
(let [client-locations (some->> (fc/field-value) :transaction-rule/client (pull-attr (dc/db conn) :client/locations))]
|
||||
(alog/peek :FP (:form-errors request))
|
||||
(let [client (some-> request :form-params :journal-entry/client)
|
||||
client-locations (some-> client :client/locations)]
|
||||
(fc/start-form (:form-params request)
|
||||
(:form-errors request)
|
||||
[:div.flex.gap-4.flex-col {:x-data (hx/json {:clientId (or (:db/id (fc/field-value (:journal-entry/client fc/*current*)))
|
||||
(:db/id (:client request)))
|
||||
:vendorId (:db/id (fc/field-value (:journal-entry/vendor fc/*current*))) })}
|
||||
(fc/with-field :journal-entry/client
|
||||
(com/validated-field
|
||||
{:label "Client"
|
||||
:errors (fc/field-errors)}
|
||||
[:div.w-96
|
||||
(com/typeahead {:name (fc/field-name)
|
||||
:error? (fc/error?)
|
||||
:class "w-96"
|
||||
:placeholder "Search..."
|
||||
:url (bidi/path-for ssr-routes/only-routes :company-search)
|
||||
:value (fc/field-value)
|
||||
:value-fn :db/id
|
||||
:content-fn :client/name
|
||||
:x-model "clientId"})]))
|
||||
(fc/with-field :journal-entry/date
|
||||
(com/validated-field
|
||||
{:label "Date"
|
||||
:errors (fc/field-errors)}
|
||||
[:div {:class "w-24"}
|
||||
(com/date-input {:value (some-> (fc/field-value)
|
||||
(atime/unparse-local atime/normal-date))
|
||||
:name (fc/field-name)
|
||||
:error? (fc/field-errors)
|
||||
:placeholder "1/1/2024"})]))
|
||||
(fc/with-field :journal-entry/vendor
|
||||
(com/validated-field
|
||||
{:label "Vendor"
|
||||
:errors (fc/field-errors)}
|
||||
[:div.w-96
|
||||
(com/typeahead {:name (fc/field-name)
|
||||
:error? (fc/error?)
|
||||
:disabled (boolean (-> request :multi-form-state :snapshot :db/id))
|
||||
:class "w-96"
|
||||
:placeholder "Search..."
|
||||
:url (bidi/path-for ssr-routes/only-routes :vendor-search)
|
||||
:value (fc/field-value)
|
||||
:value-fn :db/id
|
||||
:content-fn :vendor/name})]))
|
||||
(fc/with-field :journal-entry/amount
|
||||
(com/validated-field
|
||||
{:label "Total"
|
||||
:errors (fc/field-errors)}
|
||||
[:div {:class "w-16"}
|
||||
(com/money-input {:value (-> (fc/field-value))
|
||||
:name (fc/field-name)
|
||||
:class "w-24"
|
||||
:error? (fc/field-errors)
|
||||
:placeholder "212.44"})]))
|
||||
(fc/with-field :journal-entry/line-items
|
||||
(com/validated-field
|
||||
{:errors (fc/field-errors)}
|
||||
(com/data-grid {:headers [(com/data-grid-header {} "Account")
|
||||
(com/data-grid-header {:class "w-32"} "Location")
|
||||
(com/data-grid-header {:class "w-16"} "%")
|
||||
(com/data-grid-header {:class "w-16"} "Debit")
|
||||
(com/data-grid-header {:class "w-16"} "Credit")
|
||||
(com/data-grid-header {:class "w-16"})]}
|
||||
(fc/cursor-map #(line-item-row* % (:transaction-rule/client (fc/field-value)) client-locations))
|
||||
(com/data-grid-new-row {:colspan 4
|
||||
(fc/cursor-map #(line-item-row* % client client-locations))
|
||||
(com/data-grid-new-row {:colspan 5
|
||||
:hx-get (bidi/path-for ssr-routes/only-routes
|
||||
::route/new-line-item)
|
||||
:index (count (fc/field-value))
|
||||
:tr-params (hx/bind-alpine-vals {} {"client-id" "clientId"})}
|
||||
"New account")))))]))
|
||||
"New account"))))])))
|
||||
|
||||
|
||||
(defn new [request]
|
||||
(alog/peek ::FP (:form-params request))
|
||||
(modal-response
|
||||
(com/modal {}
|
||||
(com/modal-card {:class ""}
|
||||
[:div "New ledger entry"]
|
||||
[:div (form* request)]
|
||||
[:div (com/button {:color :primary} "Save")]))
|
||||
#_[:div]))
|
||||
(com/modal {:hx-target "this"
|
||||
:hx-indicator "this"}
|
||||
[:form {:hx-post (bidi/path-for ssr-routes/only-routes
|
||||
::route/new-submit)}
|
||||
(com/modal-card {:class "md:h-[800px] md:w-[750px] flex-col relative"
|
||||
:error (when (vector? (:form-errors request))
|
||||
(str/join ", "(:form-errors request) ))}
|
||||
[:div "New ledger entry"]
|
||||
[:div.overflow-y-scroll.relative (form* request)]
|
||||
[:div (com/button {:color :primary} "Save")])])))
|
||||
|
||||
(defn new-submit [request]
|
||||
@(dc/transact conn
|
||||
[(-> (:form-params request)
|
||||
(update :journal-entry/client :db/id)
|
||||
(update :journal-entry/vendor :db/id)
|
||||
(update :journal-entry/line-items
|
||||
(fn [li]
|
||||
(mapv
|
||||
#(update % :journal-entry-line/account :db/id)
|
||||
li)))
|
||||
(assoc :journal-entry/external-id (str "manual-" (UUID/randomUUID))))])
|
||||
|
||||
|
||||
(html-response
|
||||
[:div "GOOD"]
|
||||
:headers (cond-> {"hx-trigger" "modalclose"
|
||||
#_#_"hx-retarget" (format "#entity-table tr[data-id=\"%d\"]" (:db/id invoice))
|
||||
#_#_"hx-reswap" "outerHTML"})))
|
||||
|
||||
|
||||
(def key->handler
|
||||
(apply-middleware-to-all-handlers
|
||||
(->
|
||||
{::route/new (-> new
|
||||
#_(wrap-schema-enforce :query-schema query-schema)
|
||||
#_(wrap-form-4xx-2 profit-and-loss))
|
||||
::route/new-line-item
|
||||
#_(wrap-schema-enforce :query-schema query-schema)
|
||||
#_(wrap-form-4xx-2 profit-and-loss))
|
||||
::route/account-typeahead (-> account-typeahead
|
||||
(wrap-schema-enforce :query-schema [:map
|
||||
[:name :string]
|
||||
[:client-id {:optional true}
|
||||
[:maybe entity-id]]
|
||||
[:value {:optional true}
|
||||
[:maybe entity-id]]]))
|
||||
::route/new-submit (-> new-submit
|
||||
(wrap-schema-enforce :form-schema new-ledger-schema)
|
||||
(wrap-form-4xx-2 new))
|
||||
::route/location-select (-> location-select
|
||||
(wrap-schema-enforce :query-schema [:map
|
||||
[:name :string]
|
||||
[:client-id {:optional true}
|
||||
[:maybe entity-id]]
|
||||
[:account-id {:optional true}
|
||||
[:maybe entity-id]]]))
|
||||
::route/new-line-item
|
||||
(-> (add-new-entity-handler [:journal-entry/line-items]
|
||||
(fn render [cursor request]
|
||||
(line-item-row*
|
||||
cursor
|
||||
(:client-id (:query-params request))
|
||||
(some->> (:client-id (:query-params request)) (pull-attr (dc/db conn) :client/locations))))
|
||||
(fn build-new-row [base _]
|
||||
(assoc base :transaction-rule-account/location "Shared")))
|
||||
(wrap-schema-enforce :query-schema [:map
|
||||
[:client-id {:optional true}
|
||||
[:maybe entity-id]]]))})
|
||||
|
||||
(fn render [cursor request]
|
||||
(line-item-row*
|
||||
cursor
|
||||
(:client-id (:query-params request))
|
||||
(some->> (:client-id (:query-params request)) (pull-attr (dc/db conn) :client/locations)))))
|
||||
(wrap-schema-enforce :query-schema [:map
|
||||
[:client-id {:optional true}
|
||||
[:maybe entity-id]]]))})
|
||||
|
||||
(fn [h]
|
||||
(-> h
|
||||
#_(wrap-merge-prior-hx)
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
(ns auto-ap.ssr.utils
|
||||
(:require [auto-ap.datomic :refer [all-schema conn]]
|
||||
[auto-ap.logging :as alog]
|
||||
[auto-ap.time :as atime]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clj-time.core :as time]
|
||||
[clojure.string :as str]
|
||||
[datomic.api :as dc]
|
||||
[hiccup2.core :as hiccup]
|
||||
[hiccup.compiler :refer [HtmlRenderer render-html]]
|
||||
[malli.core :as mc]
|
||||
[malli.core :as m]
|
||||
[malli.error :as me]
|
||||
[malli.registry :as mr]
|
||||
[malli.transform :as mt2]
|
||||
[slingshot.slingshot :refer [throw+ try+]]
|
||||
[taoensso.encore :refer [filter-vals]]))
|
||||
(:require
|
||||
[auto-ap.datomic :refer [all-schema conn pull-attr]]
|
||||
[auto-ap.logging :as alog]
|
||||
[auto-ap.time :as atime]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clj-time.core :as time]
|
||||
[clojure.string :as str]
|
||||
[datomic.api :as dc]
|
||||
[hiccup.compiler :refer [HtmlRenderer render-html]]
|
||||
[hiccup2.core :as hiccup]
|
||||
[malli.core :as mc]
|
||||
[malli.core :as m]
|
||||
[malli.error :as me]
|
||||
[malli.registry :as mr]
|
||||
[malli.transform :as mt2]
|
||||
[slingshot.slingshot :refer [throw+ try+]]
|
||||
[taoensso.encore :refer [filter-vals]]))
|
||||
|
||||
(defrecord OOBElements [elements]
|
||||
HtmlRenderer
|
||||
@@ -663,3 +664,23 @@
|
||||
(defn wrap-implied-route-param [handler & {:as route-params}]
|
||||
(fn [request]
|
||||
(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]
|
||||
[: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)]
|
||||
(when (and (seq account-location)
|
||||
(not= location
|
||||
account-location))
|
||||
(throw (ex-info "Exception." {:type (str "expected " account-location)})))
|
||||
(when (and (empty? account-location)
|
||||
(= "A" location))
|
||||
|
||||
(throw (ex-info "Exception." {:type "'A' not allowed"})))
|
||||
true))
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
(def routes {"" {:get ::all-page}
|
||||
"/new" {:get ::new
|
||||
:post ::new-submit
|
||||
"/location-select" ::location-select
|
||||
"/account-typeahead" ::account-typeahead
|
||||
"/line-item" {:get ::new-line-item}}
|
||||
|
||||
"/external-new" ::external-page
|
||||
|
||||
Reference in New Issue
Block a user