diff --git a/README.md b/README.md index a48ce6c..7ec059b 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,9 @@ following keys: * :seller - the seller's (i.e. the entity to be paid) information. This is required * :buyer - the buyer's (i.e. the entity that will pay) information. This is required * :items - a list of items to be paid for - * :font-path - (optional) *the path to a font file, e.g. "/usr/share/fonts/truetype/freefont/FreeSans.ttf" - * :credentials - JIRA and Tempo access credentials. These are needed if the price depends on tracked time + * :credentials - (optional) JIRA and Tempo access credentials. These are needed if the price depends on tracked time + * :font-path - (optional) the path to a font file, e.g. "/usr/share/fonts/truetype/freefont/FreeSans.ttf" + * :callbacks - (optional) a list of commands to be called with the resulting pdf file See `resources/config.edn` for an example configuration. @@ -118,3 +119,22 @@ If a confirmation email is to be sent, a :smtp key must also be provided, e.g.: Each invoice can also be sent via email to the appropriate seller. For this to work, both the seller and the buyer must have an :email key set and the credentials must contain a :smtp key with the :smtp settings for the email server. + + +## Callbacks + +A list of additional commands can be added to each invoice. Each command will be called with +the generated invoice as its final parameter, e.g. + + {:seller {...} + :buyer {...} + :items [...] + :callbacks [["ls" "-l"] ["rm"] ["du" "-sh"]]} + +Will call the following commands (assuming that the generated invoice is `/path/to/file.pdf`): + + ls -l /path/to/file.pdf + du -sh /path/to/file.pdf + rm /path/to/file.pdf + +The last one will obviously fail, as the file no longer exists, and the error message will be displayed diff --git a/src/invoices/core.clj b/src/invoices/core.clj index fc48a5b..950de09 100644 --- a/src/invoices/core.clj +++ b/src/invoices/core.clj @@ -4,6 +4,7 @@ [invoices.jira :refer [prev-timesheet prev-month]] [clojure.tools.cli :refer [parse-opts]] [clojure.string :as str] + [clojure.java.shell :refer [sh]] [postal.core :refer [send-message]]) (:gen-class)) @@ -49,20 +50,36 @@ :error (= :SUCCESS) (println " - email sent: ")))) +(defn run-callback [file callback] + (let [command (concat callback [file]) + str-command (str/join " " command) + result (apply sh command)] + (if (= (:exit result) 0) + (println " *" str-command) + (println " X" str-command ":\n" (:err result))) + (assoc result :command str-command))) + +(defn run-callbacks [invoice callbacks] + (doall (map (partial run-callback invoice) callbacks))) + (defn date-applies? [when {to :to from :from}] (and (or (nil? to) (-> when .toString (compare to) (< 0))) (or (nil? from) (-> when .toString (compare from) (>= 0))))) -(defn for-month [when {seller :seller buyer :buyer items :items creds :credentials font-path :font-path} & [number]] - (->> - (pdf/render seller buyer - (->> items - (filter (partial date-applies? when)) - (map (partial set-price (prev-timesheet when creds)))) - (pdf/last-working-day when) - (invoice-number when number) - font-path) - (send-email (:email buyer) (:email seller) creds))) + +(defn render-month [when {seller :seller buyer :buyer items :items creds :credentials font-path :font-path} number] + (pdf/render seller buyer + (->> items + (filter (partial date-applies? when)) + (map (partial set-price (prev-timesheet when creds)))) + (pdf/last-working-day when) + (invoice-number when number) + font-path)) + +(defn for-month [when {seller :seller buyer :buyer creds :credentials callbacks :callbacks :as invoice} & [number]] + (let [file (-> when (render-month invoice number) (str ".pdf") java.io.File. .getAbsolutePath)] + (send-email (:email buyer) (:email seller) creds file) + (run-callbacks file callbacks))) (defn get-invoices [nips config] (if (seq nips) @@ -95,7 +112,7 @@ (exit 0))) (defn -main - "I don't do a whole lot ... yet." + "Generate invoice pdfs" [& args] (let [{:keys [options arguments errors summary]} (parse-opts args cli-options)] (cond @@ -104,5 +121,6 @@ (not= 1 (count arguments)) (exit -1 "No config file provided")) (println "Generating invoices") (doseq [[i invoice] (map-indexed vector (get-invoices (:company options) (first arguments)))] - (for-month (:when options) invoice (+ i (:number options)))) - )) + (for-month (:when options) invoice (+ i (:number options))) + (println))) + (shutdown-agents))