From 6077c3119ec949bae315d0d4cdbe25962c20f52e Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Fri, 13 Jan 2023 22:00:52 -0800 Subject: [PATCH] Progress on the new vendor form --- src/clj/auto_ap/square/core3.clj | 56 ++-- src/clj/auto_ap/ssr/company/company_1099.clj | 267 +++++++++++++++--- src/clj/auto_ap/ssr/core.clj | 4 +- src/clj/auto_ap/ssr/ui.clj | 3 +- src/cljc/auto_ap/ssr_routes.cljc | 4 +- .../auto_ap/views/pages/invoices/form.cljs | 1 - 6 files changed, 261 insertions(+), 74 deletions(-) diff --git a/src/clj/auto_ap/square/core3.clj b/src/clj/auto_ap/square/core3.clj index fefcf21c..ada1d9d7 100644 --- a/src/clj/auto_ap/square/core3.clj +++ b/src/clj/auto_ap/square/core3.clj @@ -441,29 +441,31 @@ (defn daily-settlements ([client location] - (de/chain (settlements client location) + (daily-settlements client location (settlements client location))) + ([client location settlements] + (de/chain settlements (fn [settlements] (log/info ::transforming-settlements) (try (->> (for [settlement settlements :let [best-sales-date (->> (d/q '[:find ?s4 (count ?s) - :in $ ?settlement-id - :where - [?settlement :expected-deposit/external-id ?settlement-id] - [?settlement :expected-deposit/charges ?c] - [?s :sales-order/charges ?c] - [?s :sales-order/date ?sales-date] - [(clj-time.coerce/to-date-time ?sales-date) ?s2] - [(auto-ap.time/localize ?s2) ?s3] - [(clj-time.coerce/to-local-date ?s3) ?s4]] - (d/db conn) - (str "square/settlement/" (:id settlement))) - (sort-by last) - last - first - coerce/to-date-time - atime/as-local-time - coerce/to-date)]] + :in $ ?settlement-id + :where + [?settlement :expected-deposit/external-id ?settlement-id] + [?settlement :expected-deposit/charges ?c] + [?s :sales-order/charges ?c] + [?s :sales-order/date ?sales-date] + [(clj-time.coerce/to-date-time ?sales-date) ?s2] + [(auto-ap.time/localize ?s2) ?s3] + [(clj-time.coerce/to-local-date ?s3) ?s4]] + (d/db conn) + (str "square/settlement/" (:id settlement))) + (sort-by last) + last + first + coerce/to-date-time + atime/as-local-time + coerce/to-date)]] #:expected-deposit {:external-id (str "square/settlement/" (:id settlement)) :vendor :vendor/ccp-square :status :expected-deposit-status/pending @@ -471,18 +473,18 @@ :client (:db/id client) :location (:square-location/client-location location) :fee (- (reduce + 0.0 (map (fn [entry] - (if (= (:type entry) "REFUND") - (- (amount->money (:fee_money entry))) - (amount->money (:fee_money entry)))) - (:entries settlement)))) + (if (= (:type entry) "REFUND") + (- (amount->money (:fee_money entry))) + (amount->money (:fee_money entry)))) + (:entries settlement)))) :date (-> (:initiated_at settlement) - (coerce/to-date)) + (coerce/to-date)) :sales-date (or best-sales-date - (-> (:initiated_at settlement) - (coerce/to-date))) + (-> (:initiated_at settlement) + (coerce/to-date))) :charges (->> (:entries settlement) - (filter :payment_id) - (map (fn [p] {:charge/external-id (str "square/charge/" (:payment_id p))})))}) + (filter :payment_id) + (map (fn [p] {:charge/external-id (str "square/charge/" (:payment_id p))})))}) (filter :expected-deposit/date) (into [])) (catch Exception e diff --git a/src/clj/auto_ap/ssr/company/company_1099.clj b/src/clj/auto_ap/ssr/company/company_1099.clj index bfdef0fe..abf2e182 100644 --- a/src/clj/auto_ap/ssr/company/company_1099.clj +++ b/src/clj/auto_ap/ssr/company/company_1099.clj @@ -1,9 +1,13 @@ (ns auto-ap.ssr.company.company-1099 (:require - [auto-ap.datomic :refer [conn]] - [auto-ap.ssr.ui :refer [base-page]] + [auto-ap.datomic :refer [conn remove-nils]] [auto-ap.graphql.utils :refer [can-see-client?]] - [datomic.api :as d])) + [auto-ap.ssr.ui :refer [base-page html-response]] + [bidi.bidi :as bidi] + [datomic.api :as d] + [hiccup2.core :as hiccup] + [clojure.string :as str])) + (defn test [x c] (println x c)) @@ -11,7 +15,8 @@ (let [valid-clients (into #{} (map :db/id (:user/clients user)))] (->> (d/q '[:find (pull ?c [:client/code]) - (pull ?v [:vendor/name + (pull ?v [:db/id + :vendor/name {:vendor/legal-entity-1099-type [:db/ident]} {:vendor/legal-entity-tin-type [:db/ident]} {:vendor/address [:address/street1 @@ -40,46 +45,222 @@ (sort-by #(:client/code (first %)) ) #_(into )))) -#_(map (fn [[client vendor amount]] - )) -(defn page [{:keys [identity]}] - (println identity) - (get-1099-companies identity) - +(defn dialog [header content footer] + [:div.modal.is-active + [:div.modal-background {"_" (hiccup/raw "on click remove <#modal-holder div/>")}] + [:div.modal-card + [:div.modal-card-head + header] + [:div.modal-card-body + content] + [:div.modal-card-foot + footer]] + [:button.modal-close.is-large {"_" (hiccup/raw "on click remove <#modal-holder div/>")}]]) + +(defn table [{:keys [identity]} & {:keys [flash-id]}] + [:table#vendor-table.table.grid.compact.is-fullwidth + [:thead + [:tr + [:th {:style {:width "5em"}}"Client"] + [:th "Vendor Name"] + [:th "Name"] + [:th {:style {:width "9em"}} "1099 Type"] + [:th {:style {:width "8em"}} "TIN"] + [:th "Address"] + [:th "Amount Paid"] + [:th {:style {:width "6em"}}] + ]] + [:tbody + (for [[client vendor amount] (get-1099-companies identity)] + [:tr (when (= flash-id + (:db/id vendor)) + {:class "live-added"}) + [:td (:client/code client)] + [:td (:vendor/name vendor)] + [:td (-> vendor :vendor/legal-entity-first-name) " " + (-> vendor :vendor/legal-entity-middle-name) " " + (-> vendor :vendor/legal-entity-last-name)] + [:td (some-> vendor :vendor/legal-entity-1099-type :db/ident name)] " " + [:td + (some-> vendor :vendor/legal-entity-tin-type :db/ident name) + (-> vendor :vendor/legal-entity-tin)] + [:td + (-> vendor :vendor/address :address/street1) " " + (-> vendor :vendor/address :address/street2) " " + (-> vendor :vendor/address :address/city) " " + (-> vendor :vendor/address :address/state) " " + (-> vendor :vendor/address :address/zip) + [:td amount] + [:td + [:button.button {:hx-get (bidi/path-for auto-ap.handler/all-routes + :company-1099-vendor-dialog + :vendor-id (:db/id vendor)) + :hx-target "#modal-holder" + :hx-swap "innerHTML"} + [:span.icon [:i.fa.fa-pencil ]]]]]])]]) + +(defn form-data->map [form-data] + (reduce-kv + (fn [acc k v] + (assoc-in acc (->> (str/split k #"_") + (mapv #(apply keyword (str/split % #"/")))) v)) + {} + form-data)) + +(defn path->name [k] + (cond (keyword? k) + (str (namespace k) "_" (name k)) + + (seq k) + (str/join "_" (map path->name k)) + :else k)) + +(defn vendor-save [{:keys [form-params identity route-params] :as request}] + (clojure.pprint/pprint form-params) + (clojure.pprint/pprint (form-data->map form-params)) + @(d/transact conn [(remove-nils {:db/id (Long/parseLong (:vendor-id route-params)) + :vendor/address (remove-nils + {:address/street1 (form-params "street1") + :address/street2 (form-params "street2") + :address/city (form-params "city") + :address/state (form-params "state") + :address/zip (form-params "zip")}) + :vendor/legal-entity-first-name (form-params "legal-entity-first-name") + :vendor/legal-entity-middle-name (form-params "legal-entity-middle-name") + :vendor/legal-entity-last-name (form-params "legal-entity-last-name") + :vendor/legal-entity-tin (form-params "legal-entity-tin") + :vendor/legal-entity-1099-type (some->> (form-params "legal-entity-1099-type") (keyword "legal-entity-1099-type" )) + :vendor/legal-entity-tin-type (some->> (form-params "legal-entity-tin-type") (keyword "legal-entity-tin-type" ))})]) + (html-response + (table request :flash-id (Long/parseLong (:vendor-id route-params))))) + + +(defn vendor-dialog [request] + (let [vendor (d/pull (d/db conn) '[* {:vendor/legal-entity-1099-type [:db/ident] + :vendor/legal-entity-tin-type [:db/ident]}] (Long/parseLong (:vendor-id (:params request))))] ;; TODO perms + (html-response + [:form {:hx-post (bidi/path-for auto-ap.handler/all-routes + :company-1099-vendor-save + :request-method :post + :vendor-id (Long/parseLong (:vendor-id (:params request)))) + :hx-target "#vendor-table" + :hx-swap "outerHTML swap:0.2s" + "_" (hiccup/raw "on htmx:afterRequest transition <#modal-holder .modal-background, #modal-holder .modal-card />'s opacity from 1.0 to 0 over 100ms then remove <#modal-holder */> ")} + (dialog + [:h4.is-4.title "Vendor 1099 Info"] + [:div + [:h3.is-3.title (:vendor/name vendor)] + + [:h4.is-4.title "Address"] + [:hr] + [:div.field + [:p.help "Street1"] + [:div.control + [:input.input.is-expanded {:type "text" + :autofocus true + :name (path->name [:vendor/address :address/street1]) + :placeholder "1700 Pennsylvania Ave" + :value (-> vendor :vendor/address :address/street1)}]]] + [:div.field + [:p.help "Street 2"] + [:div.control + [:input.input.is-expanded {:type "text" + :name (path->name [:vendor/address :address/street2]) + :placeholder "SUite 400" + :value (-> vendor :vendor/address :address/street2)}]]] + [:div.level + [:div.level-left + [:div.level-item + [:div.field + [:p.help "City"] + [:div.control + [:input.input.is-expanded {:type "text" + :placeholder "Cupertino" + :name (path->name [:vendor/address :address/city]) + :value (-> vendor :vendor/address :address/city)}]]]] + [:div.level-item + [:div.field + [:p.help "State"] + [:div.control + [:input.input.is-expanded {:type "text" + :style {:width "3em"} + :placeholder "CA" + :name (path->name [:vendor/address :address/state]) + :value (-> vendor :vendor/address :address/state)}]]]] + [:div.level-item + [:div.field + [:p.help "Zip"] + [:div.control + [:input.input.is-expanded {:type "text" + :placeholder "95014" + :name (path->name [:vendor/address :address/zip]) + :value (-> vendor :vendor/address :address/zip)}]]]]]] + [:h4.is-4.title "Legal Entity"] + [:hr] + [:div.level + [:div.level-left + [:div.level-item + [:div.field + [:p.help "First Name"] + [:div.control + [:input.input.is-expanded {:type "text" + :placeholder "Josh" + :name (path->name [:vendor/legal-entity-first-name]) + :value (-> vendor :vendor/legal-entity-first-name)}]]]] + [:div.level-item + [:div.field + [:p.help "Middle Name"] + [:div.control + [:input.input.is-expanded {:type "text" + :placeholder "Caleb" + :name (path->name [:vendor/legal-entity-middle-name]) + :value (-> vendor :vendor/legal-entity-middle-name)}]]]] + [:div.level-item + [:div.field + [:p.help "Last Name"] + [:div.control + [:input.input.is-expanded {:type "text" + :placeholder "Smith" + :name (path->name [:vendor/legal-entity-last-name]) + :value (-> vendor :vendor/legal-entity-last-name)}]]]]]] + + [:div.level + [:div.level-left + [:div.level-item + [:div.field + [:p.help "TIN"] + [:div.control + [:input.input {:type "text" + :name (path->name [:vendor/legal-entity-tin]) + :placeholder "SSN or EIN" + :size "12" + :value (-> vendor :vendor/legal-entity-tin)}]]]] + [:div.level-item + [:div.field + [:p.help "TIN Type"] + [:div.control + [:div.select + [:select {:name (path->name [:vendor/legal-entity-tin-type])} + [:option {:value ""} ""] + [:option {:value "ein" :selected (= (-> vendor :vendor/legal-entity-tin-type :db/ident) :legal-entity-tin-type/ein)} "EIN"] + [:option {:value "ssn" :selected (= (-> vendor :vendor/legal-entity-tin-type :db/ident) :legal-entity-tin-type/ssn)} "SSN"]]]]]] + [:div.level-item + [:div.field + [:p.help "1099 Type"] + [:div.control + [:div.select + [:select {:name (path->name [:vendor/legal-entity-1099-type])} + [:option {:value ""} ""] + [:option {:value "none" :selected (= (-> vendor :vendor/legal-entity-1099-type :db/ident) :legal-entity-1099-type/none)} "None"] + [:option {:value "misc" :selected (= (-> vendor :vendor/legal-entity-1099-type :db/ident) :legal-entity-1099-type/misc)} "Misc"] + [:option {:value "landlord" :selected (= (-> vendor :vendor/legal-entity-1099-type :db/ident) :legal-entity-1099-type/landlord)} "Landlord"]]]]]]]]] + [:button.button.is-primary "Save"])]))) + + + +(defn page [{:keys [identity] :as request}] (base-page [:div - [:table.table.grid.compact.is-fullwidth - [:thead - [:tr - [:td {:style {:width "5em"}}"Client"] - [:td "Vendor Name"] - [:td "Name"] - [:td {:style {:width "9em"}} "1099 Type"] - [:td {:style {:width "8em"}} "TIN"] - [:td "Address"] - [:td "Amount Paid"] - [:td {:style {:width "6em"}}] - ]] - [:tbody - (for [[client vendor amount] (get-1099-companies identity)] - [:tr - [:td (:client/code client)] - [:td (:vendor/name vendor)] - [:td (-> vendor :vendor/legal-entity-first-name) " " - (-> vendor :vendor/legal-entity-middle-name) " " - (-> vendor :vendor/legal-entity-last-name)] - [:td (some-> vendor :vendor/legal-entity-1099-type :db/ident name)] " " - [:td - (some-> vendor :vendor/legal-entity-tin-type :db/ident name) - (-> vendor :vendor/legal-entity-tin)] - [:td - (-> vendor :vendor/address :address/street1) " " - (-> vendor :vendor/address :address/street2) " " - (-> vendor :vendor/address :address/city) " " - (-> vendor :vendor/address :address/state) " " - (-> vendor :vendor/address :address/zip) - [:td amount] - [:td]]]) - ]]] + (table request)] [:div])) diff --git a/src/clj/auto_ap/ssr/core.clj b/src/clj/auto_ap/ssr/core.clj index e5bfafa5..9eb6cd7d 100644 --- a/src/clj/auto_ap/ssr/core.clj +++ b/src/clj/auto_ap/ssr/core.clj @@ -9,5 +9,7 @@ (def key->handler {:admin-history (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin admin/history))) :admin-history-search (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin admin/history-search))) :admin-history-inspect (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin admin/inspect))) - :company-1099 (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin company-1099/page)))}) + :company-1099 (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin company-1099/page))) + :company-1099-vendor-dialog (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin company-1099/vendor-dialog))) + :company-1099-vendor-save (wrap-client-redirect-unauthenticated (wrap-secure (wrap-admin company-1099/vendor-save)))}) diff --git a/src/clj/auto_ap/ssr/ui.clj b/src/clj/auto_ap/ssr/ui.clj index a95fd1fc..332f6d11 100644 --- a/src/clj/auto_ap/ssr/ui.clj +++ b/src/clj/auto_ap/ssr/ui.clj @@ -70,7 +70,8 @@ [:div {:class "inbox-messages"} contents]]] [:div] - [:div {:id "dz-hidden"}]]]]])) + [:div {:id "dz-hidden"}]]] + [:div#modal-holder]]])) (defn html-response [hiccup & {:keys [status] :or {status 200}}] {:status status diff --git a/src/cljc/auto_ap/ssr_routes.cljc b/src/cljc/auto_ap/ssr_routes.cljc index f26766e5..cbd0d10a 100644 --- a/src/cljc/auto_ap/ssr_routes.cljc +++ b/src/cljc/auto_ap/ssr_routes.cljc @@ -5,5 +5,7 @@ #"/search/?" :admin-history-search ["/" [#"\d+" :entity-id] #"/?"] :admin-history-search ["/inspect/" [#"\d+" :entity-id] #"/?"] :admin-history-inspect}} - "company" {"/1099" :company-1099}}) + "company" {"/1099" :company-1099 + "/1099/vendor-dialog" {["/" [#"\d+" :vendor-id]] {:get :company-1099-vendor-dialog + :post :company-1099-vendor-save}}}}) diff --git a/src/cljs/auto_ap/views/pages/invoices/form.cljs b/src/cljs/auto_ap/views/pages/invoices/form.cljs index eb5f32f8..c094ddc0 100644 --- a/src/cljs/auto_ap/views/pages/invoices/form.cljs +++ b/src/cljs/auto_ap/views/pages/invoices/form.cljs @@ -108,7 +108,6 @@ (re-frame/inject-cofx ::inject/sub (fn [[_ _ _ client]] [::subs/locations-for-client (:id client)]))] (fn [{:keys [db] ::subs/keys [locations-for-client]} [_ _ command client]] - (println locations-for-client) (when (= :create command) {:db (-> db