diff --git a/resources/public/js/htmx-disable.js b/resources/public/js/htmx-disable.js index c0f97709..38083f9d 100644 --- a/resources/public/js/htmx-disable.js +++ b/resources/public/js/htmx-disable.js @@ -184,6 +184,41 @@ function getFourWeekPeriodsPeriods(endDate) { ]; } + const getTwelveCalendarMonthsPeriods = (endDate) => { + console.log(endDate) + // If no date is provided, default to today's date + const today = endDate ? parseMMDDYYYY(endDate) : new Date(); + + // Set the last day of the provided month as the end date + const inputEndDate = new Date(today.getFullYear(), today.getMonth() + 1, 0); + + // Calculate the start of the total year range (12 months back from the end of input month) + const totalStartDate = new Date(inputEndDate.getFullYear(), inputEndDate.getMonth() - 11, 1); + + // Build the array of months + + // Build the array of months + const months = [ + { + start: formatDateMMDDYYYY(totalStartDate), + end: formatDateMMDDYYYY(inputEndDate), + title: "Total" + }, + ...Array.from({ length: 12 }, (_, i) => { + const monthEnd = new Date(inputEndDate.getFullYear(), inputEndDate.getMonth() - (11 - i) + 1, 0); // Last day of the month + const monthStart = new Date(monthEnd.getFullYear(), monthEnd.getMonth(), 1); // First day of the month + return { + start: formatDateMMDDYYYY(monthStart), + end: formatDateMMDDYYYY(monthEnd), + title: monthEnd.toLocaleString('default', { month: 'long', year: 'numeric' }) + }; + }) + ]; + console.log(months) + + return months; +}; + const withLastYear = (date) => { if (!date) { diff --git a/src/clj/auto_ap/ssr/components/inputs.clj b/src/clj/auto_ap/ssr/components/inputs.clj index 1e3b0049..460f1454 100644 --- a/src/clj/auto_ap/ssr/components/inputs.clj +++ b/src/clj/auto_ap/ssr/components/inputs.clj @@ -338,6 +338,7 @@ [:div.shrink {:x-data (hx/json {:value (:value params) :tippy nil :dp nil}) + "x-effect" "console.log('changed to' +value)" "@change-date.camel" "$dispatch('change')" } [:input diff --git a/src/clj/auto_ap/ssr/components/periods.clj b/src/clj/auto_ap/ssr/components/periods.clj index 3c75111a..d7aa4217 100644 --- a/src/clj/auto_ap/ssr/components/periods.clj +++ b/src/clj/auto_ap/ssr/components/periods.clj @@ -18,8 +18,9 @@ :end (atime/unparse-local atime/normal-date))}) + :x-effect "console.log('periods are', periods)" :x-init "$watch('periods', ds => source_date= ds.length > 0 ? ds[0].end : null)" } - [:template {:x-for "(v,n) in periods"} + [:template {:x-for "(v,n) in periods" ":key" "n"} [:div [:input {:type "hidden" ":name" "'periods[' + n + '][start]'" @@ -57,6 +58,8 @@ (buttons/a-button- {"@click" "periods=[calendarYearPeriod(source_date)]"} [:span "Calendar year (" [:span {:x-text "parseMMDDYYYY(source_date).getFullYear()"}] ")"]) + (buttons/a-button- {"@click" "periods=getTwelveCalendarMonthsPeriods(source_date)"} [:span "12 months, ending " + [:span {:x-text "parseMMDDYYYY(source_date).toLocaleString('default', { month: 'long' })"}]]) [:hr {:class "h-px my-1 bg-gray-200 border-0 dark:bg-gray-700"} ] (buttons/a-button- {"@click" "periods=getLastMonthPeriods()"} "Last Month") (buttons/a-button- {"@click" "periods=getMonthToDatePeriods()"} "Month to date") diff --git a/src/clj/auto_ap/ssr/grid_page_helper.clj b/src/clj/auto_ap/ssr/grid_page_helper.clj index 831e4ab7..5c68ed3a 100644 --- a/src/clj/auto_ap/ssr/grid_page_helper.clj +++ b/src/clj/auto_ap/ssr/grid_page_helper.clj @@ -242,6 +242,9 @@ true (wrap-secure) true (wrap-client-redirect-unauthenticated))) +;; TODO oob-render is wonky, requires thinking about accidental side effects. Really only used in a small handful of cases. probably best to just +;; use alpine for those cases, or make it so that date filters issue a change event when they render. for example, when you click on "month", +;; make it so that it rerenders the date range component, along with a hx-trigger change header (defn csv-route [{:keys [fetch-page headers page->csv-entities]} & {:keys []}] (cond-> (fn csv-route [{:keys [identity] :as request}] diff --git a/src/clj/auto_ap/ssr/transaction.clj b/src/clj/auto_ap/ssr/transaction.clj index da413847..1138973f 100644 --- a/src/clj/auto_ap/ssr/transaction.clj +++ b/src/clj/auto_ap/ssr/transaction.clj @@ -5,7 +5,7 @@ :refer [add-sorter-fields apply-pagination apply-sort-4 conn merge-query observable-query pull-many]] [auto-ap.graphql.utils :refer [extract-client-ids]] - [auto-ap.permissions :refer [can? wrap-must]] + [auto-ap.permissions :refer [wrap-must]] [auto-ap.query-params :refer [wrap-copy-qp-pqp]] [auto-ap.routes.transactions :as route] [auto-ap.routes.utils :refer [wrap-client-redirect-unauthenticated]] @@ -19,11 +19,12 @@ [auto-ap.ssr.svg :as svg] [auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers clj-date-schema - entity-id html-response main-transformer strip - wrap-merge-prior-hx wrap-schema-enforce]] + entity-id html-response strip wrap-merge-prior-hx + 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] [hiccup.util :as hu] [malli.core :as mc])) @@ -82,8 +83,7 @@ :value (:vendor (:query-params request)) :value-fn :db/id :content-fn :vendor/name})) - (com/field {:label "Bank Account"} - (bank-account-filter* request)) + (bank-account-filter* request) (date-range-field* request) @@ -140,8 +140,10 @@ (seq (:description args)) (merge-query {:query {:in ['?description] - :where ['[?e :transaction/description-original ?description]]} - :args [(:description args)]}) + :where ['[?e :transaction/description-original ?do] + '[(clojure.string/lower-case ?do) ?do2] + '[(.contains ?do2 ?description)]]} + :args [(str/lower-case (:description args))]}) (:amount-gte args) (merge-query {:query {:in ['?amount-gte] @@ -259,6 +261,10 @@ :page-specific-nav filters :fetch-page fetch-page :query-schema query-schema + :oob-render + (fn [request] + [(assoc-in (date-range-field* request) [1 :hx-swap-oob] true) + (assoc-in (exact-match-id* request) [1 :hx-swap-oob] true)]) :action-buttons (fn [request] [(com/button {:color :primary :hx-get (bidi/path-for ssr-routes/only-routes @@ -266,17 +272,17 @@ "Add Transaction")]) :row-buttons (fn [request entity] [#_(when (and (can? (:identity request) {:subject :transaction :activity :edit})) - (com/icon-button {:hx-put (bidi/path-for ssr-routes/only-routes - ::route/edit-wizard - :db/id (:db/id entity))} - svg/pencil)) + (com/icon-button {:hx-put (bidi/path-for ssr-routes/only-routes + ::route/edit-wizard + :db/id (:db/id entity))} + svg/pencil)) #_(when (and (can? (:identity request) {:subject :transaction :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 delete this transaction?"} - svg/trash))]) - + (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 delete this transaction?"} + svg/trash))]) + :breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes ::route/page)} "Transactions"]] :title (fn [r] @@ -284,15 +290,15 @@ :entity-name "register" :route ::route/table :csv-route ::route/csv -:break-table (fn [request entity] - (cond - (= (-> request :query-params :sort first :name) "Vendor") - (or (-> entity :transaction/vendor :vendor/name) - "No vendor") - - - - :else nil)) + :break-table (fn [request entity] + (cond + (= (-> request :query-params :sort first :name) "Vendor") + (or (-> entity :transaction/vendor :vendor/name) + "No vendor") + + + + :else nil)) :page->csv-entities (fn [[transactions]] transactions) :headers [{:key "id" @@ -310,11 +316,11 @@ {:key "vendor" :name "Vendor" :sort-key "vendor" - :render (fn [e] + :render (fn [e] #_(alog/peek :vend e) - (or - (-> e :transaction/vendor :vendor/name) - [:span.italic.text-gray-400 (-> e :transaction/description-simple)])) + (or + (-> e :transaction/vendor :vendor/name) + [:span.italic.text-gray-400 (-> e :transaction/description-simple)])) :render-csv (fn [e] (or (-> e :transaction/vendor :vendor/name) (-> e :transaction/description-simple)))} {:key "description" @@ -333,7 +339,7 @@ :sort-key "amount" :class "text-right" :render #(format "$%,.2f" (:transaction/amount %)) - :render-csv :transaction/amount } + :render-csv :transaction/amount} {:key "links" :name "Links" :show-starting "lg" @@ -348,11 +354,11 @@ {:exact-match-id (:db/id (:transaction/payment i))}) :color :primary :content (format "Payment '%s'" (-> i :transaction/payment :payment/invoice-number))}) - + (and (:transaction/client-overrides i) (seq (:transaction/client-overrides i))) {:link (hu/url (bidi/path-for client-routes/routes - :transactions) - {:exact-match-id (:db/id i)}) + :transactions) + {:exact-match-id (:db/id i)}) :color :primary :content "Client Overrides"}))) :render-for #{:html}}]}))