From fa00563195d9dba31deab8c6b5d7b327034c02fc Mon Sep 17 00:00:00 2001 From: Robert Einsle Date: Sat, 25 Feb 2017 20:02:48 +0100 Subject: [PATCH] carom/carom-doc#8 Calculate prize using normal and happy hour prize --- billard/models.py | 16 +++++++-- billard/templatetags/display_client.py | 9 ++++- billard/utils.py | 50 +++++++++++++++++++++++--- 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/billard/models.py b/billard/models.py index 95d695d..e99a635 100644 --- a/billard/models.py +++ b/billard/models.py @@ -71,10 +71,19 @@ class Desk(models.Model): def accounting_for(self): t = Accounting.objects.filter(client=self.client, desk_no=self.desk_no)[:3][::-1] + client = self.client + location = client.location if t.__len__() > 0: a = t[t.__len__() - 1] if a.time_to is None: - prize = utils.get_prize_for(start=a.time_from, end=datetime.now(timezone.utc), pph=self.prize) + prize = utils.get_prize_for( + start=a.time_from, + end=datetime.now(timezone.utc), + pph=self.prize, + hh_start=location.happy_hour_start, + hh_end=location.happy_hour_end, + pphh=self.prize_hh, + ) if prize != a.prize: a.prize = prize return t @@ -148,7 +157,10 @@ def process_location_data(): acc.prize = utils.get_prize_for( start=acc.time_from, end=ld.tst, - pph=desk.prize + pph=desk.prize, + hh_start=cli.location.happy_hour_start, + hh_end=cli.location.happy_hour_end, + pphh=desk.prize_hh, ) acc.save() ld.delete() diff --git a/billard/templatetags/display_client.py b/billard/templatetags/display_client.py index bc4805d..a5f2d0d 100644 --- a/billard/templatetags/display_client.py +++ b/billard/templatetags/display_client.py @@ -21,7 +21,14 @@ def display_client(client, desk_no): a = acc[-1] if a.time_to is None: alert = 'alert-info' - prize = utils.get_prize_for(start=a.time_from, end=datetime.now(), pph=desk.prize) + prize = utils.get_prize_for( + start=a.time_from, + end=datetime.now(), + pph=desk.prize, + hh_start=desk.client.location.happy_hour_start, + hh_end=desk.client.location.happy_hour_end, + pphh=desk.prize_hh, + ) prize = '{0:.2f}'.format(prize) if prize != a.prize: a.prize = prize diff --git a/billard/utils.py b/billard/utils.py index 2e5edf7..328adff 100644 --- a/billard/utils.py +++ b/billard/utils.py @@ -1,16 +1,56 @@ -from datetime import datetime +from datetime import datetime, date, time, timedelta -def get_prize_for(start, end, pph=0): +def get_prize_for(start, end, pph=0, hh_start=None, hh_end=None, pphh=0): """ calculate prize of billard table rental :param start: start datetime of rental :param end: end datetime of rental :param pph: prize per hour of rental + :param hh_start: start of happy hour + :param hh_end: end of happy hour + :param pphh: prize per hour in happy hour :return: the calculated prize of rental """ - pps = pph / 3600 - time = (end - start).seconds - prize = round((pps * time), 1) + if end <= start: + raise ValueError('end date must be after start date') + prize = 0 + if hh_start is not None and hh_end is not None: + d = start.date() + t = start.time() + end_date = end.date() + end_time = end.time() + while True: + if t < hh_start: + if end_time < hh_start and d == end_date: + prize += calculate_prize_for(start=t, end=end_time, pph=pph) + break + else: + prize += calculate_prize_for(start=t, end=hh_start, pph=pph) + t = hh_start + elif hh_start <= t < hh_end: + if end_time < hh_end and d == end_date: + prize += calculate_prize_for(start=t, end=end_time, pph=pphh) + break + else: + prize += calculate_prize_for(start=t, end=hh_end, pph=pphh) + t = hh_end + else: + if d == end_date: + prize += calculate_prize_for(start=t, end=end_time, pph=pph) + break + else: + prize += calculate_prize_for(start=t, end=datetime.strptime('23:59:59', '%H:%M:%S').time(), pph=pph) + t = datetime.strptime('00:00:00', '%H:%M:%S').time() + d = (datetime.combine(d, t) + timedelta(days=1)).date() + else: + prize = calculate_prize_for(start=start, end=end, pph=pph) return prize + + +def calculate_prize_for(start, end, pph=0): + pps = pph / 3600 + d = date.today() + t = (datetime.combine(d, end) - datetime.combine(d, start)).seconds + return round((pps * t), 1)