;; This buffer is for Clojure experiments and evaluation.

;; Press C-j to evaluate the last expression.

;; You can also press C-u C-j to evaluate the expression and pretty-print its result.

(def potential-dups 
  (->> (d/q '[:find ?tx ?amount ?date ?ba
              :in $ 
              :where
              [?ba :bank-account/intuit-bank-account]
              [?tx :transaction/bank-account ?ba]
              [?tx :transaction/amount ?amount]
              [?tx :transaction/date ?date]
              (not [?tx :transaction/approval-status :transaction-approval-status/suppressed])]
            (d/db auto-ap.datomic/conn))
       (group-by (fn [[tx amount date ba]]
                   [amount date ba]))
       (filter (fn [[g txes]]
                 (> (count txes) 1)))
       (vals)))

(def ids-to-suppress 
  (let [db (d/db auto-ap.datomic/conn)]
    (->> potential-dups
         (map (fn [tx-ids]
                (d/q '[:find (pull ?t [:db/id :transaction/description-original :transaction/raw-id]) ?d
                       :in $ $$ [?t ...]
                       :where
                       [$$ ?t :transaction/id _ ?tx true]
                       [?tx :db/txInstant ?d]]
                     db (d/history db)
                     (map first tx-ids))
                ))
         (filter (fn [tx-sets]
                   (some (fn [[_ added-date]]
                           (t/after? (c/to-date-time added-date) (c/to-date-time  #inst "2021-12-01")))
                         tx-sets)))
         (mapcat (fn [tx-sets]
                   (->> tx-sets 
                        (map (fn [[tx-data]]
                               (let [alternate-description (str/replace (:transaction/description-original tx-data) #" \d+$" "" )
                                     alternate-id (first (d/q '[:find [?alternate ...]
                                                                :in $ [?alternate ...] ?t-num ?ad
                                                                :where [?alternate :transaction/description-original ?ad]
                                                                (not [(= ?alternate ?t-num)])]
                                                              db
                                                              (map (comp :db/id first) tx-sets)
                                                              (:db/id tx-data)
                                                              alternate-description))]
                                 [(:db/id tx-data)
                                  alternate-id])))
                        (filter last)
                        set)))

         (map (fn [pairs]
                (d/pull-many
                 db
                 [:db/id :transaction/description-original :transaction/bank-account :transaction/amount :transaction/date {:transaction/payment [:db/id :payment/date :payment/amount :payment/check-number]}]
                 pairs)))
         (map (fn [[l r]]
                (cond (and (:transaction/payment l)
                           (:transaction/payment r))
                      (:db/id r)

                      (:transaction/payment l)
                      (:db/id r)

                      (:transaction/payment r)
                      (:db/id l)

                      :else
                      (:db/id r)))))))


(count ids-to-suppress)

(clojure.pprint/pprint 
 (mapcat (fn [i]
           (let [transaction (d/entity (d/db auto-ap.datomic/conn) i)
                 payment-id (-> transaction :transaction/payment :db/id)
                 expected-deposit-id (-> transaction :transaction/expected-deposit :db/id)
                 transaction-tx {:db/id i
                                 :transaction/approval-status :transaction-approval-status/suppressed}]
             (cond->> [{:db/id "datomic.tx"
                        :db/doc "Fixing duplicates caused by missing number"}
                       transaction-tx
                       [:db/retractEntity [:journal-entry/original-entity i]]]
               payment-id (into [{:db/id payment-id
                                  :payment/status :payment-status/pending}
                                 [:db/retract (:db/id transaction) :transaction/payment payment-id]])
               expected-deposit-id (into [{:db/id expected-deposit-id
                                           :expected-deposit/status :expected-deposit-status/pending}
                                          [:db/retract (:db/id transaction) :transaction/expected-deposit expected-deposit-id]]))))
         ids-to-suppress))

(auto-ap.datomic/audit-transact-batch
 (mapcat (fn [i]
           (let [transaction (d/entity (d/db auto-ap.datomic/conn) i)
                 payment-id (-> transaction :transaction/payment :db/id)
                 expected-deposit-id (-> transaction :transaction/expected-deposit :db/id)
                 transaction-tx {:db/id i
                                 :transaction/approval-status :transaction-approval-status/suppressed}]
             (cond->> [{:db/id "datomic.tx"
                        :db/doc "Fixing duplicates caused by missing number"}
                       transaction-tx
                       [:db/retractEntity [:journal-entry/original-entity i]]]
               payment-id (into [{:db/id payment-id
                                  :payment/status :payment-status/pending}
                                 [:db/retract (:db/id transaction) :transaction/payment payment-id]])
               expected-deposit-id (into [{:db/id expected-deposit-id
                                           :expected-deposit/status :expected-deposit-status/pending}
                                          [:db/retract (:db/id transaction) :transaction/expected-deposit expected-deposit-id]]))))
         ids-to-suppress)    
     {:user/role ":admin"
      :user/name "Bryce"})


(take 10 potential-dups)

[[#:transaction{:description-original "Check Paid - 233 - Check Paid 233"} #inst "2021-12-17T18:46:15.419-00:00"]
 [#:transaction{:description-original "Check Paid - 233 - Check Paid 233"} #inst "2021-12-17T06:10:34.587-00:00"]
 [#:transaction{:description-original "Check Paid - 233 - Check Paid"} #inst "2021-12-18T06:02:24.053-00:00"]
 ]
[[{:db/id 17592251275669,
   :transaction/description-original "CHECK 4136"} #inst "2021-12-18T06:04:25.450-00:00"]
 [{:db/id 17592251219175, :transaction/description-original "CHECK 4136 4136"} #inst "2021-12-17T19:01:35.161-00:00"]]

(entity-history 17592251219175);; => [[13194204708070 :transaction/location "A"] [13194204708070 :transaction/bank-account 17592220107992] [13194204708070 :transaction/check-number 4136] [13194204708070 :transaction/status "POSTED"] [13194204708070 :transaction/raw-id "2021-12-15T00:00:00.000-08:00-17592220107992-CHECK 4136 4136--252.0-0-17592219470393"] [13194204708070 :transaction/payment 17592250880737] [13194204708070 :transaction/vendor 17592236287037] [13194204708070 :transaction/accounts 17592251219176] [13194204708070 :transaction/id "d74f6f645e9e31e1f22d65a1eb41fcfa0c5f0a439c903f562f4b146e3945410f"] [13194204708070 :transaction/description-original "CHECK 4136 4136"] [13194204708070 :transaction/amount -252.0] [13194204708070 :transaction/date #inst "2021-12-15T08:00:00.000-00:00"] [13194204708070 :transaction/client 17592219470393] [13194204708070 :transaction/approval-status 17592231963877]]

(entity-history 13194204708070)

(clojure.pprint/pprint (auto-ap.intuit.core/get-transactions "2021-12-01" "2021-12-30" "NGSM - City National - Main - 5955 ---NGSM-CN5955"))




@(d/transact auto-ap.datomic/conn (->> (d/q '[:find ?ba ?d
                                             :in $ $$
                                             :where [?ba :bank-account/name]
                                             (not [?ba :bank-account/type])
                                             [$$ ?ba :bank-account/type ?t _ true]
                                             [?t :db/ident ?d]
                                             ]
                                           (d/db auto-ap.datomic/conn)
                                           (d/history (d/db auto-ap.datomic/conn)))
                                      (map (fn [[ba t]]
                                             {:db/id ba
                                              :bank-account/type t}))))

[[{:db/id 17592251275311,
   :transaction/raw-id
   "2021-12-06T00:00:00.000-08:00-17592232886804-Credit (Any Type) Deposit-256.05-0-17592232886786"}
  #inst "2021-12-18T06:03:45.924-00:00"]
 [{:db/id 17592251196869,
   :transaction/raw-id
   "2021-12-06T00:00:00.000-08:00-17592232886804-Credit (Any Type) Deposit 108981169-256.05-0-17592232886786"}
  #inst "2021-12-17T18:46:15.419-00:00"]
 [{:db/id 17592251196869,
   :transaction/raw-id
   "2021-12-06T00:00:00.000-08:00-17592232886804-Credit (Any Type) Deposit 108981169-256.05-0-17592232886786"}
  #inst "2021-12-17T06:12:30.538-00:00"]]

(clojure.pprint/pprint (entity-history 17592251189853))
(clojure.pprint/pprint (entity-history 17592250137454))

(clojure.pprint/pprint (entity-history 13194204678748))

(clojure.pprint/pprint (entity-history 13194203626349))

(clojure.pprint/pprint (tx-detail 13194204678748))





(def potential-dups 
  (let [problem-date? (fn [[_ date-added]]
                        (t/within?
                         (t/interval 
                          (c/to-date-time #inst "2021-12-16T00:00:00-08:00")
                          (c/to-date-time #inst "2021-12-18T00:00:00-08:00"))
                         (c/to-date-time date-added)))]
    (->> (d/q '[:find ?tx ?date-added ?check-number ?amount ?date ?ba
                :in $ $$
                :where
                [?ba :bank-account/intuit-bank-account]
                [?tx :transaction/bank-account ?ba]
                [?tx :transaction/amount ?check-number]
                [?tx :transaction/amount ?amount]
                [$$ ?tx :transaction/date ?date ?dtx true]
                [$$ ?dtx :db/txInstant ?date-added]
                (not [?tx :transaction/approval-status :transaction-approval-status/suppressed])]
              (d/db auto-ap.datomic/conn)
              (d/history (d/db auto-ap.datomic/conn)))
         (group-by (fn [[tx date-added check-number amount date ba]]
                     [check-number amount date ba]))
         (filter (fn [[g txes]]
                   (and 
                    (> (count txes) 1)
                    (not (every? problem-date? txes))
                    (some problem-date? txes))))
         (vals))))

(def ids-to-suppress (->> potential-dups
                            (map (fn [dup-set]
                                   (last 
                                    (->> dup-set 
                                         (sort-by (fn [[_ date-added]]
                                                    date-added))
                                         (map (fn [[tx]]
                                                tx))
                                         ))))))

(auto-ap.datomic/audit-transact-batch
 (mapcat (fn [i]
           (let [transaction (d/entity (d/db auto-ap.datomic/conn) i)
                 payment-id (-> transaction :transaction/payment :db/id)
                 expected-deposit-id (-> transaction :transaction/expected-deposit :db/id)
                 transaction-tx {:db/id i
                                 :transaction/approval-status :transaction-approval-status/suppressed}]
             (cond->> [{:db/id "datomic.tx"
                        :db/doc "Fixing duplicates caused by change in check text"}
                       transaction-tx
                       [:db/retractEntity [:journal-entry/original-entity i]]]
               payment-id (into [{:db/id payment-id
                                  :payment/status :payment-status/pending}
                                 [:db/retract (:db/id transaction) :transaction/payment payment-id]])
               expected-deposit-id (into [{:db/id expected-deposit-id
                                           :expected-deposit/status :expected-deposit-status/pending}
                                          [:db/retract (:db/id transaction) :transaction/expected-deposit expected-deposit-id]]))))
         ids-to-suppress)    
     {:user/role ":admin"
      :user/name "Bryce"})


(count potential-dups)
(clojure.pprint/pprint potential-dups)
17592250137454

(entity-history 17592248570305)

(entity-history 13194202059200)

(entity-history 17592248569907)
(entity-history 13194202058802)

(doc every?)
