diff --git a/src/clj/app/insurance/controller.clj b/src/clj/app/insurance/controller.clj index 4bda05a..bac531a 100644 --- a/src/clj/app/insurance/controller.clj +++ b/src/clj/app/insurance/controller.clj @@ -612,12 +612,15 @@ (defn download-changes-excel [{:keys [db] :as req}] (let [policy-id (util.http/path-param-uuid! req :policy-id) - policy (q/retrieve-policy db policy-id) - {:keys [attachment-filename]} (util.http/unwrap-params req) - _ (assert "attachment-filename") + {:keys [attachment-filename preview-type] :as p} (-> req :params) + _ (assert preview-type) + _ (assert attachment-filename) output-stream (ByteArrayOutputStream.) - file-bytes (.toByteArray (excel/generate-excel-changeset! policy output-stream))] + changeset-scope (condp = preview-type + "new" #{:instrument.coverage.change/new} + "changes" #{:instrument.coverage.change/changed :instrument.coverage.change/removed}) + file-bytes (.toByteArray (excel/generate-excel-changeset! changeset-scope policy output-stream))] {:status 200 :headers {"Content-Disposition" (format "%s; filename*=UTF-8''%s" "attachment" (URLEncoder/encode attachment-filename "UTF-8")) "Content-Type" "application/vnd.ms-excel" @@ -635,14 +638,16 @@ (defn send-changes! [{:keys [db] :as req}] (let [policy-id (util.http/path-param-uuid! req :policy-id) - {:keys [attachment-filename] :as p} (util.http/unwrap-params req) - _ (assert "attachment-filename") + {:keys [attachment-filename-changes attachment-filename-new] :as p} (:params req) + _ (tap> [:send-changes! (:params req)]) + _ (assert attachment-filename-changes) + _ (assert attachment-filename-new) policy (q/retrieve-policy db policy-id) {:keys [subject recipient body]} p smtp (-> req :system :env :smtp-sno) from (:from smtp)] - (excel/send-email! policy smtp from recipient subject body attachment-filename) - (confirm-and-activate-policy req (util.http/path-param-uuid! req :policy-id)))) + (excel/send-email! policy smtp from recipient subject body attachment-filename-new attachment-filename-changes) + #_(confirm-and-activate-policy req (util.http/path-param-uuid! req :policy-id)))) (defn instrument-coverage-history [{:keys [db] :as req} {:instrument.coverage/keys [coverage-id instrument] :as coverage}] (let [instr-id (:instrument/instrument-id instrument) diff --git a/src/clj/app/insurance/domain.clj b/src/clj/app/insurance/domain.clj index f8a152b..a495b57 100644 --- a/src/clj/app/insurance/domain.clj +++ b/src/clj/app/insurance/domain.clj @@ -61,7 +61,7 @@ (defn update-total-coverage-price "Given a policy and a specific instrument coverage, calculate the total price for the instrument" [policy {:instrument.coverage/keys [value instrument] :as coverage}] - ;; value * category factor * premium factor * coverage factor + ;; value * category factor * premium factor * coverage factor (let [category-id (-> instrument :instrument/category :instrument.category/category-id) _ (assert category-id) category-factor (get (make-category-factor-lookup policy) category-id) diff --git a/src/clj/app/insurance/excel.clj b/src/clj/app/insurance/excel.clj index e581a03..9a4a47a 100644 --- a/src/clj/app/insurance/excel.clj +++ b/src/clj/app/insurance/excel.clj @@ -70,12 +70,13 @@ (defn -add-instruments! [sheet normal-style stuckpreis-style total-style label-style title items] (when (seq items) - (add-label-row! sheet title label-style) + (when title + (add-label-row! sheet title label-style)) (doseq [item items] (let [row (excel/add-row! sheet item)] (set-item-styles! row normal-style stuckpreis-style total-style))))) -(defn- generate-excel [fname output-fname new-items changed-items removed-items] +(defn- generate-excel [fname output-fname {changed-items :instrument.coverage.change/changed removed-items :instrument.coverage.change/removed new-items :instrument.coverage.change/new :as cs}] (let [wb (excel/load-workbook-from-resource fname) sheet (excel/select-sheet SHEET-NAME wb) total-style (get-cell-style-at sheet 4 TOTAL-COL) @@ -90,34 +91,39 @@ date-today (t/format (t/formatter "dd MMM yyyy" Locale/GERMAN) (t/today)) add-instruments! (partial -add-instruments! sheet normal-style stuckpreis-style total-style label-style)] (clear-rows! sheet) - (add-instruments! (format "Neue Instrumente: (Ab %s)" date-today) new-items) - (add-blank-rows! sheet 3 normal-style) - (add-instruments! (format "Änderungen: (Ab %s)" date-today) changed-items) - (add-blank-rows! sheet 3 normal-style) - (add-instruments! (format "Entfernung: (Ab %s)" date-today) removed-items) + (when new-items + ;; they don't like the new items to have a title + (add-instruments! nil new-items) + (add-blank-rows! sheet 3 normal-style)) + (when changed-items + (add-instruments! (format "Änderungen: (Ab %s)" date-today) changed-items) + (add-blank-rows! sheet 3 normal-style)) + (when removed-items + (add-instruments! (format "Entfernung: (Ab %s)" date-today) removed-items)) (excel/save-workbook! output-fname wb))) -(defn generate-excel-changeset! [{:insurance.policy/keys [covered-instruments] :as policy} output] - (let [changed (into [] (filter #(= :instrument.coverage.change/changed (:instrument.coverage/change %)) covered-instruments)) - removed (into [] (filter #(= :instrument.coverage.change/removed (:instrument.coverage/change %)) covered-instruments)) - new (into [] (filter #(= :instrument.coverage.change/new (:instrument.coverage/change %)) covered-instruments))] +(defn generate-excel-changeset! [changeset-scope {:insurance.policy/keys [covered-instruments] :as policy} output] + (let [gather-changeset (fn [scope] + (into [] (filter #(= scope (:instrument.coverage/change %)) covered-instruments))) + changesets (into {} (map (fn [k] [k (map coverage->row (gather-changeset k))]) changeset-scope))] - (generate-excel "insurance-changes-template.xls" output - (map coverage->row new) - (map coverage->row changed) - (map coverage->row removed))) + (generate-excel "insurance-changes-template.xls" output changesets)) output) -(defn send-email! [policy smtp-params from to subject body attachment-filename] +(defn send-email! [policy smtp-params from to subject body attachment-filename-new attachment-filename-changes] (with-open [conn (tarayo/connect smtp-params)] - (let [output-stream (ByteArrayOutputStream.)] - (generate-excel-changeset! policy output-stream) + (let [new-items-output-stream (ByteArrayOutputStream.) + changed-items-output-stream (ByteArrayOutputStream.)] + (generate-excel-changeset! #{:instrument.coverage.change/new} policy new-items-output-stream) + (generate-excel-changeset! #{:instrument.coverage.change/changed :instrument.coverage.change/removed} policy changed-items-output-stream) (tarayo/send! conn {:from from :to to :subject subject :body [{:content body} - {:content (.toByteArray output-stream) - :content-type "application/vnd.ms-excel" :filename attachment-filename}]})))) + {:content (.toByteArray new-items-output-stream) + :content-type "application/vnd.ms-excel" :filename attachment-filename-new} + {:content (.toByteArray changed-items-output-stream) + :content-type "application/vnd.ms-excel" :filename attachment-filename-changes}]})))) (comment diff --git a/src/clj/app/insurance/routes.clj b/src/clj/app/insurance/routes.clj index 7a9261f..d9ab91f 100644 --- a/src/clj/app/insurance/routes.clj +++ b/src/clj/app/insurance/routes.clj @@ -147,6 +147,14 @@ (insurance-detail) (insurance-notification) + ["/insurance-changes-excel-download/{policy-id}/" + {:get {:summary "Download the changes excel file" + :parameters {:query [:map + [:preview-type [:enum "new" "changes"]] + [:attachment-filename :string]]} + :handler (fn [req] + (view/insurance-policy-changes-excel-download req))}}] + ["/insurance-changes-excel/{policy-id}/" {:post {:summary "Get the changes excel file" :parameters {} diff --git a/src/clj/app/insurance/views.clj b/src/clj/app/insurance/views.clj index bd2bca5..640fa12 100644 --- a/src/clj/app/insurance/views.clj +++ b/src/clj/app/insurance/views.clj @@ -177,12 +177,22 @@ [:p {:class "flex items-center text-sm text-gray-500"} premium-factor]]]]])) +(defn insurance-policy-changes-excel-download [req] + (controller/download-changes-excel req)) + (defn insurance-policy-changes-file [{:keys [db] :as req}] (let [policy-id (util.http/path-param-uuid! req :policy-id) {:keys [action] :as p} (util.http/unwrap-params req)] (condp = action "preview" - (controller/download-changes-excel req) + (let [{:keys [preview-type] :as p} (util.http/unwrap-params req) + _ (assert preview-type) + attachment-filename (get (util.http/unwrap-params req) (keyword (str "attachment-filename-" preview-type))) + _ (assert attachment-filename) + url (urls/link-policy-changes-download-excel policy-id preview-type attachment-filename)] + (if (:htmx? req) + (response/hx-redirect url) + (response/redirect url))) "send" (do (controller/send-changes! req) @@ -203,9 +213,14 @@ member (auth/get-current-member req) sender (:member/name member) subject (format "Aktualisierung %s" policy-number) - attachment-filename (format "AnlageÄnderungen-%s.xls" (t/format (t/formatter "yyyy-M-d") (t/today)))] + attachments [{:title "Neue Instrumente" + :type "new" + :filename (format "AnlageNeueInstrumente-%s.xls" (t/format (t/formatter "yyyy-M-d") (t/today)))} + {:title "Änderungen/Entfernung" + :type "changes" + :filename (format "AnlageÄnderungen-%s.xls" (t/format (t/formatter "yyyy-M-d") (t/today)))}]] - ;; (excel/generate-excel-changeset! policy nil) + ;; (excel/generate-excel-changeset! policy nil) [:div {:class "bg-white shadow py-4 px-6 space-y-12"} [:form {:action (urls/link-policy-changes-confirm policy) :method :post} @@ -236,6 +251,8 @@ Anbei finden Sie die neuesten Änderungen unserer Versicherungspolice für die Instrumente unserer Band. Bitte nehmen Sie sich einen Moment Zeit, um die Aktualisierungen durchzugehen. +Sie finden einen Anhang mit den neuen Elementen und einen zweiten Anhang mit den Änderungen und Entfernungen. + Für Rückfragen oder weitere Informationen stehe ich Ihnen gerne zur Verfügung. Mit freundlichen Grüßen, @@ -243,18 +260,22 @@ Mit freundlichen Grüßen, " recipient-title recipient-name sender)]]] - [:div {:class "col-span-full"} - [:label {:for "photo", :class "block text-sm font-medium leading-6 text-gray-900"} "Anhang"] - [:div {:class "mt-2 flex items-center gap-x-3"} - (icon/file-excel-outline {:class "h-12 w-12 text-gray-300"}) - [:div {:class "mt-2 w-full space-y-2"} - [:div {:class "flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-sno-orange-600 sm:max-w-lg"} - [:input {:type :text :name "attachment-filename" :value attachment-filename - :id "attachment-filename" :class "block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6"}]] - [:button {:type :submit :class "rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50" - :name "action" - :value "preview"} - "Vorschau"]]]]] + (map-indexed (fn [idx {:keys [filename type title]}] + (assert type) + [:div {:class "col-span-full"} + [:label {:for "photo", :class "block text-sm font-medium leading-6 text-gray-900"} (str "Anhang " (inc idx) ": " title)] + [:div {:class "mt-2 flex items-center gap-x-3"} + (icon/file-excel-outline {:class "h-12 w-12 text-gray-300"}) + [:div {:class "mt-2 w-full space-y-2"} + [:div {:class "flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-sno-orange-600 sm:max-w-lg"} + [:input {:type :text :name (str "attachment-filename-" type) :value filename :class "attachment-filename block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6"}]] + [:button {:type :button :class "rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50" + :name "action" + :hx-post (urls/link-policy-changes-confirm policy) + :hx-include "input.attachment-filename" + :hx-vals {"preview-type" type} + :value "preview"} + "Vorschau"]]]]) attachments)] [:div {:class "mt-6 flex items-center justify-end gap-x-6"} (ui/button :label (tr [:action/cancel]) :priority :white diff --git a/src/clj/app/urls.clj b/src/clj/app/urls.clj index eb3f123..e121815 100644 --- a/src/clj/app/urls.clj +++ b/src/clj/app/urls.clj @@ -33,6 +33,13 @@ (def link-policy (partial link-helper "/insurance-policy/" :insurance.policy/policy-id)) (def link-policy-send-notifications (partial link-helper "/insurance-policy-notify/" :insurance.policy/policy-id)) (def link-policy-changes (partial link-helper "/insurance-policy-changes/" :insurance.policy/policy-id)) + +(defn link-policy-changes-download-excel [policy preview-type attachment-filename] + (str + (link-helper "/insurance-changes-excel-download/" :insurance.policy/policy-id policy) + "?preview-type=" preview-type + "&attachment-filename=" (url-encode attachment-filename))) + (def link-policy-changes-confirm (partial link-helper "/insurance-changes-excel/" :insurance.policy/policy-id)) (defn link-policy-table-member [policy-or-policy-id member-or-member-id] (link-policy policy-or-policy-id (str "/#coverages-" (entity-id :member/member-id member-or-member-id))))