Skip to content

Instantly share code, notes, and snippets.

@rap1ds
Created May 3, 2013
Embed
What would you like to do?
Daily allowance calculation by country, city and start and end dates
(def country-list
{:fi {:default {:full 3900 :big 2600 :small 1300}}
:de {:default {:full 2400 :big 1200 :small 600}}
:uk {:default {:full 4200 :big 2800 :small 1400}
:london {:full 5700 :big 3800 :small 1900}}})
(defn country-allowance
([country]
(country-allowance country "default"))
([country city]
(if-let [c ((keyword country) country-list)]
(get c (keyword city) (:default c))
(throw (Exception. "You fool!")))))
(defn end-of-day
"return end of the day (midnight)"
[day]
(ct/plus (ct/date-time (ct/year day) (ct/month day) (ct/day day)) (ct/days 1)))
(defn start-of-day
"return start of the day (midnight)"
[day]
(ct/date-time (ct/year day) (ct/month day) (ct/day day)))
(defn big-small
[interval]
(let [h (ct/in-hours interval)]
(cond
(>= 14 h 8) {:full 0 :small 1 :big 0}
(> h 14) {:full 0 :small 0 :big 1}
:else {:full 0 :small 0 :big 0})))
(defn allowance-days
"takes start and end and returns allowance days"
[start end]
(let [end-of-first (end-of-day start)
end-of-last (end-of-day end)]
(if (not= end-of-first end-of-last)
(let [start-of-last (start-of-day end)
fd (ct/in-days (ct/interval end-of-first start-of-last))
edges (map big-small [(ct/interval start end-of-first) (ct/interval start-of-last end)])]
(merge-with + {:full fd :big 0 :small 0} (nth edges 0) (nth edges 1)))
(big-small (ct/interval start end)))))
(defn calc-allowance
[claim]
(let [ca (country-allowance (:destinationCountry claim) (:destinationCity claim))
adays (allowance-days (:startDate claim) (:endDate claim))]
(->>
(merge-with * ca adays)
vals
(reduce +))))
@rap1ds
Copy link
Author

rap1ds commented May 3, 2013

Credits to @ovan !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment