   (doseq [item (:items transaction)]
     (as-> item i
       (assoc i :transaction-id (:id transaction))
-      (before-save-item i)
       (upsert-item storage i))))
 
 (defn- find-base-item

      (if (validation/has-error? validated)
        validated
        (do
        (let [existing (find-existing-transaction storage transaction)
              dereferenced-items (->> (:items existing)
                                     (remove #(some (fn [i] (= (:id i)
                                                               (:id %)))
                                                    (:items validated))))
              recalc-base-date (earlier (:transaction-date existing)
                                        (:transaction-date validated))
              recalc-account-ids (->> (:items validated)
                                   (concat dereferenced-items)
                                   (map :account-id)
                                   (into #{}))]
              (update-full-transaction storage validated)
              (doseq [account-id recalc-account-ids]
                (recalculate-account storage account-id recalc-base-date))))))))

(defn- get-preceding-items
  "Returns the items that precede each item in the

  (let [base-item (find-base-item storage account-id as-of)
        items (search-items storage
                            {:account-id account-id
                             :transaction-date [:>= as-of]}
                            {:sort [:transaction-date :index]})
        account (accounts/find-by-id storage account-id)
        [last-index
         balance] (process-items storage account base-item items)]
    ; TODO only update account if balance is not nil
    (accounts/update storage (assoc account :quantity balance))))

; Processing a transaction
; 1. Save the transaction and item records
