Makes editing work correctly for non-admins
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
(ns auto-ap.ssr.components.aside
|
||||
(:require [auto-ap.client-routes :as client-routes]
|
||||
[auto-ap.logging :as alog]
|
||||
[auto-ap.permissions :refer [can?]]
|
||||
[auto-ap.routes.admin.clients :as ac-routes]
|
||||
[auto-ap.routes.admin.excel-invoices :as ei-routes]
|
||||
[auto-ap.routes.admin.import-batch :as ib-routes]
|
||||
[auto-ap.routes.outgoing-invoice :as oi-routes]
|
||||
[auto-ap.routes.admin.transaction-rules :as transaction-rules]
|
||||
[auto-ap.routes.admin.vendors :as v-routes]
|
||||
[auto-ap.routes.invoice :as invoice-route]
|
||||
[auto-ap.routes.outgoing-invoice :as oi-routes]
|
||||
[auto-ap.routes.payments :as payment-routes]
|
||||
[auto-ap.ssr-routes :as ssr-routes]
|
||||
[auto-ap.ssr.hiccup-helper :as hh]
|
||||
@@ -131,53 +131,56 @@
|
||||
:active? (= ::invoice-route/voided-page (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Voided")
|
||||
(menu-button- {:href (bidi/path-for ssr-routes/only-routes
|
||||
::oi-routes/new)
|
||||
:active? (= ::oi-routes/new (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Create outgoing"))
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:import-invoices)} "Import")
|
||||
#_(menu-button- {:href (bidi/path-for ssr-routes/only-routes
|
||||
::oi-routes/new)
|
||||
:active? (= ::oi-routes/new (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Create outgoing"))
|
||||
|
||||
(menu-button- {:icon svg/receipt-register-1
|
||||
(when
|
||||
(can? (:identity request) {:subject :sales :activity :read})
|
||||
(list
|
||||
(menu-button- {:icon svg/receipt-register-1
|
||||
|
||||
"@click.prevent" "if (selected == 'sales') {selected = null } else { selected = 'sales'} "}
|
||||
"Sales")
|
||||
(sub-menu- {:selector "sales"
|
||||
:active? (= "sales" selected)}
|
||||
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
|
||||
:pos-sales)
|
||||
"?date-range=week")
|
||||
:active? (= :pos-sales (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Sales")
|
||||
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
|
||||
:pos-expected-deposits)
|
||||
"?date-range=week")
|
||||
:active? (= :pos-expected-deposits (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Expected Deposits")
|
||||
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
|
||||
:pos-tenders)
|
||||
"?date-range=week")
|
||||
:active? (= :pos-tenders (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Tenders")
|
||||
"@click.prevent" "if (selected == 'sales') {selected = null } else { selected = 'sales'} "}
|
||||
"Sales")
|
||||
(sub-menu- {:selector "sales"
|
||||
:active? (= "sales" selected)}
|
||||
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
|
||||
:pos-sales)
|
||||
"?date-range=week")
|
||||
:active? (= :pos-sales (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Sales")
|
||||
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
|
||||
:pos-expected-deposits)
|
||||
"?date-range=week")
|
||||
:active? (= :pos-expected-deposits (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Expected Deposits")
|
||||
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
|
||||
:pos-tenders)
|
||||
"?date-range=week")
|
||||
:active? (= :pos-tenders (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Tenders")
|
||||
|
||||
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
|
||||
:pos-refunds)
|
||||
"?date-range=week")
|
||||
:active? (= :pos-refunds (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
|
||||
:pos-refunds)
|
||||
"?date-range=week")
|
||||
:active? (= :pos-refunds (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
|
||||
"Refunds")
|
||||
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
|
||||
:pos-cash-drawer-shifts)
|
||||
"?date-range=week")
|
||||
:active? (= :cash-drawer-shifts (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Cash drawer shifts"))))
|
||||
|
||||
"Refunds")
|
||||
(menu-button- {:href (str (bidi/path-for ssr-routes/only-routes
|
||||
:pos-cash-drawer-shifts)
|
||||
"?date-range=week")
|
||||
:active? (= :cash-drawer-shifts (:matched-route request))
|
||||
:hx-boost "true"}
|
||||
"Cash drawer shifts"))
|
||||
;; TODO make specific routes for categories
|
||||
;; TODO auto-apen sub menus
|
||||
|
||||
(menu-button- {"@click.prevent" "if (selected == 'payments') {selected = null } else { selected = 'payments'} "
|
||||
:icon svg/payments}
|
||||
"Payments")
|
||||
@@ -224,26 +227,35 @@
|
||||
:requires-feedback-transactions)} "Client Review")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:approved-transactions)} "Approved")
|
||||
(menu-button- {:href (bidi/path-for ssr-routes/only-routes
|
||||
:transaction-insights)} "Insights"))]
|
||||
(when (can? (:identity request)
|
||||
{:subject :transaction :activity :insights})
|
||||
(menu-button- {:href (bidi/path-for ssr-routes/only-routes
|
||||
:transaction-insights)} "Insights")))]
|
||||
|
||||
(menu-button- {"@click.prevent" "if (selected == 'ledger') {selected = null } else { selected = 'ledger'} "
|
||||
:icon svg/receipt}
|
||||
"Ledger")
|
||||
(sub-menu- {:selector "ledger"
|
||||
:active? (= "ledger" selected)}
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:ledger)} "Register")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:profit-and-loss)} "Profit & Loss")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:profit-and-loss-detail)} "Profit & Loss Detail")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:cash-flows)} "Cash Flows")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:balance-sheet)} "Balance Sheet")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:external-import-ledger)} "External Ledger Import"))]))
|
||||
|
||||
(when (can? (:identity request)
|
||||
{:subject :ledger-page})
|
||||
(list
|
||||
(menu-button- {"@click.prevent" "if (selected == 'ledger') {selected = null } else { selected = 'ledger'} "
|
||||
:icon svg/receipt}
|
||||
"Ledger")
|
||||
(sub-menu- {:selector "ledger"
|
||||
:active? (= "ledger" selected)}
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:ledger)} "Register")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:profit-and-loss)} "Profit & Loss")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:profit-and-loss-detail)} "Profit & Loss Detail")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:cash-flows)} "Cash Flows")
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:balance-sheet)} "Balance Sheet")
|
||||
(when (can? (:identity request)
|
||||
{:subject :ledger
|
||||
:activity :import})
|
||||
(menu-button- {:href (bidi/path-for client-routes/routes
|
||||
:external-import-ledger)} "External Ledger Import")))))]))
|
||||
|
||||
|
||||
(defn company-aside-nav- [_]
|
||||
@@ -330,7 +342,7 @@
|
||||
:active? (= :admin-rules matched-route)
|
||||
:href (bidi/path-for ssr-routes/only-routes
|
||||
:admin-history)
|
||||
:hx-boost "true" }
|
||||
:hx-boost "true"}
|
||||
"History")]
|
||||
|
||||
[:li
|
||||
@@ -342,9 +354,10 @@
|
||||
"Background Jobs")]
|
||||
|
||||
|
||||
(menu-button- {:icon svg/arrow-in
|
||||
"@click.prevent" "if (selected == 'import') {selected = null } else { selected = 'import'} "}
|
||||
"Import")
|
||||
(when (can? (:identity request) {:subject :invoice :activity :import})
|
||||
(menu-button- {:icon svg/arrow-in
|
||||
"@click.prevent" "if (selected == 'import') {selected = null } else { selected = 'import'} "}
|
||||
"Import"))
|
||||
|
||||
(sub-menu- {:selector "import"}
|
||||
(menu-button- {:href (bidi/path-for ssr-routes/only-routes
|
||||
@@ -356,10 +369,10 @@
|
||||
(menu-button- {:href (bidi/path-for ssr-routes/only-routes
|
||||
::ib-routes/page)
|
||||
:active? (= ::ib-routes/page matched-route)
|
||||
:hx-boost true}
|
||||
:hx-boost true}
|
||||
"Import Batches")
|
||||
(menu-button- {:href (bidi/path-for ssr-routes/only-routes
|
||||
:admin-ezcater-xls)
|
||||
:active? (= :admin-ezcater-xls matched-route)
|
||||
:hx-boost "true"}
|
||||
:hx-boost "true"}
|
||||
"EZCater XLS Import"))])
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
:hx-swap "outerHTML"
|
||||
:hx-target-400 "#form-errors .error-content"
|
||||
:hx-trigger "submit"
|
||||
:hx-target "this"
|
||||
"x-trap" "true"})
|
||||
:hx-target "this" })
|
||||
|
||||
(defprotocol ModalWizardStep
|
||||
(step-key [this])
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[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]]
|
||||
@@ -69,8 +70,6 @@
|
||||
(defn check-vendor-default-account [vendor-id]
|
||||
(some? (:vendor/default-account (get-vendor vendor-id))))
|
||||
|
||||
;; TODO negative expense accounts for negative invoices?
|
||||
|
||||
(def new-form-schema
|
||||
[:map
|
||||
[:db/id {:optional true} [:maybe entity-id]]
|
||||
@@ -97,7 +96,7 @@
|
||||
[:fn {:error/message "Not an allowed account."}
|
||||
check-allowance]]]
|
||||
[:invoice-expense-account/location :string]
|
||||
[:invoice-expense-account/amount [:double {:min 0}]]]
|
||||
[:invoice-expense-account/amount :double]]
|
||||
[:fn {:error/fn (fn [r x] (:type r))
|
||||
:error/path [:invoice-expense-account/location]} check-invoice-expense-account-location]]]]])
|
||||
|
||||
@@ -557,36 +556,67 @@
|
||||
(when-not (dollars= total expense-account-total)
|
||||
(form-validation-error (str "Expense account total (" expense-account-total ") does not equal invoice total (" total ")")))))
|
||||
|
||||
(defn maybe-spread-locations [invoice]
|
||||
(let [valid-locations (pull-attr (dc/db conn) :client/locations (:invoice/client invoice))]
|
||||
(with-precision 2
|
||||
(let [expense-accounts (vec (mapcat
|
||||
(fn [ea]
|
||||
(let [cents-to-distribute (int (Math/round (Math/abs (* (:invoice-expense-account/amount ea) 100))))]
|
||||
(if (= "Shared" (:invoice-expense-account/location ea))
|
||||
(->> valid-locations
|
||||
(map
|
||||
(fn [cents location]
|
||||
(assoc ea
|
||||
:db/id (random-tempid)
|
||||
:invoice-expense-account/amount (* 0.01 cents)
|
||||
:invoice-expense-account/location location))
|
||||
(rm/spread-cents cents-to-distribute (count valid-locations))))
|
||||
[ea])))
|
||||
(:invoice/expense-accounts invoice)))
|
||||
expense-accounts (mapv
|
||||
(fn [a]
|
||||
(update a :invoice-expense-account/amount
|
||||
#(with-precision 2
|
||||
(double (.setScale (bigdec %) 2 java.math.RoundingMode/HALF_UP)))))
|
||||
expense-accounts)
|
||||
leftover (with-precision 2 (.round (bigdec (- (Math/abs (:invoice/total invoice))
|
||||
(Math/abs (reduce + 0.0 (map #(:invoice-expense-account/amount %) expense-accounts)))))
|
||||
*math-context*))
|
||||
accounts (if (seq expense-accounts)
|
||||
(update-in expense-accounts [(dec (count expense-accounts)) :invoice-expense-account/amount] #(+ % (double leftover)))
|
||||
[])]
|
||||
(assoc invoice :invoice/expense-accounts (into [] accounts))))))
|
||||
|
||||
(defn- calculate-spread
|
||||
"Helper function to calculate the amount to be assigned to each location"
|
||||
[shared-amount total-locations]
|
||||
(let [base-amount (int (/ shared-amount total-locations))
|
||||
remainder (- shared-amount (* base-amount total-locations))]
|
||||
{:base-amount base-amount
|
||||
:remainder remainder}))
|
||||
|
||||
|
||||
(defn- spread-expense-account
|
||||
"Spreads the expense account amount across the given locations"
|
||||
[locations expense-account]
|
||||
(if (= "Shared" (:invoice-expense-account/location expense-account))
|
||||
(let [{:keys [base-amount remainder]} (calculate-spread (:invoice-expense-account/amount expense-account) (count locations))]
|
||||
(map-indexed (fn [idx _]
|
||||
(assoc expense-account
|
||||
:invoice-expense-account/amount (+ base-amount (if (< idx remainder) 1 0))
|
||||
:invoice-expense-account/location (nth locations idx)))
|
||||
locations))
|
||||
[expense-account]))
|
||||
|
||||
(defn $->cents [x]
|
||||
(int
|
||||
(let [result (* 100M (bigdec x))]
|
||||
(.setScale result 0 java.math.BigDecimal/ROUND_HALF_UP))))
|
||||
|
||||
(defn cents->$ [x]
|
||||
(double
|
||||
(let [result (* 0.01M (bigdec x))]
|
||||
(.setScale result 2 java.math.BigDecimal/ROUND_HALF_UP))))
|
||||
|
||||
(defn- apply-total-delta-to-account [invoice-total eas]
|
||||
(when (seq eas)
|
||||
(let [leftover (- invoice-total (reduce + 0 (map :invoice-expense-account/amount eas)))
|
||||
leftover-beyond-a-single-cent? (or (< leftover -1)
|
||||
(> leftover 1))
|
||||
leftover (if leftover-beyond-a-single-cent?
|
||||
0
|
||||
leftover)
|
||||
[first-eas & rest] eas]
|
||||
(cons
|
||||
(update first-eas :invoice-expense-account/amount #(+ % leftover))
|
||||
rest))))
|
||||
|
||||
|
||||
(defn maybe-spread-locations
|
||||
"Converts any expense account for a \"Shared\" location into a separate expense account for all valid locations for that client"
|
||||
([invoice]
|
||||
(maybe-spread-locations invoice (pull-attr (dc/db conn) :client/locations (:invoice/client invoice))))
|
||||
([invoice locations]
|
||||
(update-in invoice
|
||||
[:invoice/expense-accounts]
|
||||
(fn [expense-accounts]
|
||||
(->> expense-accounts
|
||||
(map (fn [ea] (update ea :invoice-expense-account/amount $->cents)))
|
||||
(mapcat (partial spread-expense-account locations))
|
||||
(apply-total-delta-to-account ($->cents (:invoice/total invoice)))
|
||||
(map (fn [ea] (update ea :invoice-expense-account/amount cents->$))))))))
|
||||
|
||||
|
||||
|
||||
(defrecord NewWizard2 [_ current-step]
|
||||
mm/LinearModalWizard
|
||||
@@ -622,9 +652,27 @@
|
||||
new-form-schema)
|
||||
(submit [this {:keys [multi-form-state request-method identity] :as request}]
|
||||
(let [invoice (:snapshot multi-form-state)
|
||||
|
||||
_ (alog/peek invoice)
|
||||
extant? (:db/id invoice)
|
||||
client-id (->db-id (:invoice/client invoice))
|
||||
vendor-id (->db-id (:invoice/vendor invoice))
|
||||
paid-amount (if-let [outstanding-balance
|
||||
(and extant?
|
||||
(-
|
||||
(pull-attr (dc/db conn)
|
||||
:invoice/total
|
||||
(:db/id invoice))
|
||||
(pull-attr (dc/db conn)
|
||||
:invoice/outstanding-balance
|
||||
(:db/id invoice))))]
|
||||
outstanding-balance
|
||||
0.0)
|
||||
outstanding-balance (- (or
|
||||
(:invoice/total (:step-params multi-form-state))
|
||||
(:invoice/total (:snapshot multi-form-state)))
|
||||
paid-amount)
|
||||
|
||||
transaction [:upsert-invoice (-> multi-form-state
|
||||
:snapshot
|
||||
(assoc :db/id (or (:db/id invoice) "invoice"))
|
||||
@@ -638,11 +686,11 @@
|
||||
:invoice-expense-account/amount (or (:invoice/total (:step-params multi-form-state))
|
||||
(:invoice/total (:snapshot multi-form-state)))}]))
|
||||
(assoc
|
||||
:invoice/outstanding-balance (or
|
||||
(:invoice/total (:step-params multi-form-state))
|
||||
(:invoice/total (:snapshot multi-form-state)))
|
||||
:invoice/outstanding-balance outstanding-balance
|
||||
:invoice/import-status :import-status/imported
|
||||
:invoice/status :invoice-status/unpaid)
|
||||
:invoice/status (if (dollars= 0.0 outstanding-balance)
|
||||
:invoice-status/paid
|
||||
:invoice-status/unpaid))
|
||||
(maybe-spread-locations)
|
||||
(update :invoice/date coerce/to-date)
|
||||
(update :invoice/due coerce/to-date)
|
||||
|
||||
@@ -401,17 +401,19 @@
|
||||
(when (can? (:identity request) {:subject :invoice :activity :create})
|
||||
(com/button {:hx-get (bidi/path-for ssr-routes/only-routes ::route/new-wizard)}
|
||||
"New invoice"))])
|
||||
:row-buttons (fn [_ entity]
|
||||
[(when (= :invoice-status/unpaid (:invoice/status entity))
|
||||
:row-buttons (fn [request entity]
|
||||
[(when (and (= :invoice-status/unpaid (:invoice/status entity))
|
||||
(can? (:identity request) {:subject :invoice :activity :delete}))
|
||||
(com/icon-button {:hx-delete (bidi/path-for ssr-routes/only-routes
|
||||
::route/delete
|
||||
:db/id (:db/id entity))
|
||||
:hx-confirm "Are you sure you want to void this invoice?"}
|
||||
svg/trash))
|
||||
(com/icon-button {:hx-put (bidi/path-for ssr-routes/only-routes
|
||||
::route/edit-wizard
|
||||
:db/id (:db/id entity)) }
|
||||
svg/pencil)])
|
||||
(when (can? (:identity request) {:subject :invoice :activity :edit})
|
||||
(com/icon-button {:hx-put (bidi/path-for ssr-routes/only-routes
|
||||
::route/edit-wizard
|
||||
:db/id (:db/id entity))}
|
||||
svg/pencil))])
|
||||
:breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes ::route/page)}
|
||||
"Invoices"]]
|
||||
:title (fn [r]
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
[com.brunobonacci.mulog.buffer :as rb]
|
||||
[config.core :refer [env]]
|
||||
[datomic.api :as dc]
|
||||
[puget.printer :as puget]
|
||||
[datomic.api :as d]
|
||||
[figwheel.main.api]
|
||||
[hawk.core]
|
||||
@@ -27,30 +28,32 @@
|
||||
(:import (org.apache.commons.io.input BOMInputStream)
|
||||
[org.eclipse.jetty.server.handler.gzip GzipHandler]))
|
||||
|
||||
|
||||
(defn println-event [item]
|
||||
(printf "%s: %s - %s:%s by %s\n"
|
||||
(str (c/to-date-time (:mulog/timestamp item)))
|
||||
(:mulog/namespace item) (:mulog/event-name item)
|
||||
(if (:mulog/duration item)
|
||||
(str " " (int (/ (:mulog/duration item) 1000000)) "ms")
|
||||
"")
|
||||
(:user-name item))
|
||||
(println (reduce
|
||||
(fn [acc [k v]]
|
||||
(assoc acc k v))
|
||||
{}
|
||||
(dissoc
|
||||
item
|
||||
:user)))
|
||||
#_(puget/cprint (reduce
|
||||
(fn [acc [k v]]
|
||||
(assoc acc k v))
|
||||
{}
|
||||
(dissoc
|
||||
item
|
||||
:user))
|
||||
{:seq-limit 10})
|
||||
#_(printf "%s: %s - %s:%s by %s\n"
|
||||
(str (c/to-date-time (:mulog/timestamp item)))
|
||||
(:mulog/namespace item) (:mulog/event-name item)
|
||||
(if (:mulog/duration item)
|
||||
(str " " (int (/ (:mulog/duration item) 1000000)) "ms")
|
||||
"")
|
||||
(:user-name item))
|
||||
#_(println (reduce
|
||||
(fn [acc [k v]]
|
||||
(assoc acc k v))
|
||||
{}
|
||||
(dissoc
|
||||
item
|
||||
:user)))
|
||||
(when (= :auto-ap.logging/peek (:mulog/event-name item))
|
||||
(println "\u001B[31mTEST")
|
||||
)
|
||||
(puget/cprint (reduce
|
||||
(fn [acc [k v]]
|
||||
(assoc acc k v))
|
||||
{}
|
||||
(dissoc
|
||||
item
|
||||
:user))
|
||||
{:seq-limit 10})
|
||||
(println))
|
||||
|
||||
|
||||
@@ -354,7 +357,7 @@
|
||||
`src` or `resources`."
|
||||
[]
|
||||
(println "starting auto reset")
|
||||
(hawk.core/watch! [{:paths ["src/"]
|
||||
(hawk.core/watch! [{:paths ["src/" "test/"]
|
||||
:handler auto-reset-handler}]))
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,24 @@
|
||||
(#{:invoice-page :payment-page :my-company-page :transaction-page :ledger-page} subject)
|
||||
true
|
||||
|
||||
(= [:invoice :import] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :create] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :pay] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :edit] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :delete] [subject activity])
|
||||
true
|
||||
|
||||
(= [:sales :read] [subject activity])
|
||||
true
|
||||
|
||||
(= [:vendor :create] [subject activity])
|
||||
true
|
||||
|
||||
@@ -44,6 +62,18 @@
|
||||
(= [:vendor :edit] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :create] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :pay] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :edit] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :delete] [subject activity])
|
||||
true
|
||||
|
||||
:else false)
|
||||
|
||||
(#{:user-role/read-only "read-only"} role)
|
||||
@@ -66,6 +96,19 @@
|
||||
(= [:signature :edit] [subject activity])
|
||||
true
|
||||
|
||||
|
||||
(= [:invoice :create] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :pay] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :edit] [subject activity])
|
||||
true
|
||||
|
||||
(= [:invoice :delete] [subject activity])
|
||||
true
|
||||
|
||||
:else false)
|
||||
|
||||
:else
|
||||
|
||||
Reference in New Issue
Block a user