Only generate bill if no overlap

This commit is contained in:
fnux 2020-03-01 15:47:27 +01:00
parent be2b0a8855
commit 4f25086a63
2 changed files with 27 additions and 14 deletions

View file

@ -6,7 +6,7 @@ from django.db.models import Q
from .models import Bill, Payment, PaymentMethod, Order from .models import Bill, Payment, PaymentMethod, Order
from django.utils import timezone from django.utils import timezone
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from dateutil.relativedelta import relativedelta from calendar import monthrange
def sum_amounts(entries): def sum_amounts(entries):
return reduce(lambda acc, entry: acc + entry.amount, entries, 0) return reduce(lambda acc, entry: acc + entry.amount, entries, 0)
@ -25,18 +25,24 @@ def get_payment_method_for(user):
return None return None
def beginning_of_month(date): def beginning_of_month(year, month):
return datetime(year=date.year, date=now.month, day=0) tz = timezone.get_current_timezone()
return datetime(year=year, month=month, day=1, tzinfo=tz)
def end_of_month(year, month):
(_, days) = monthrange(year, month)
tz = timezone.get_current_timezone()
return datetime(year=year, month=month, day=days,
hour=23, minute=59, second=59, tzinfo=tz)
def generate_bills_for(year, month, user, allowed_delay): def generate_bills_for(year, month, user, allowed_delay):
# /!\ We exclusively work on the specified year and month. # /!\ We exclusively work on the specified year and month.
# Default values for next bill (if any). Only saved at the end of # Default values for next bill (if any). Only saved at the end of
# this method, if relevant. # this method, if relevant.
tz = timezone.get_current_timezone()
next_bill = Bill(owner=user, next_bill = Bill(owner=user,
starting_date=datetime(year=year, month=month, day=1, tzinfo=tz), starting_date=beginning_of_month(year, month),
ending_date=datetime(year=year, month=month, day=28, tzinfo=tz), ending_date=end_of_month(year, month),
creation_date=timezone.now(), creation_date=timezone.now(),
due_date=timezone.now() + allowed_delay) due_date=timezone.now() + allowed_delay)
@ -52,7 +58,7 @@ def generate_bills_for(year, month, user, allowed_delay):
unpaid_orders = [] unpaid_orders = []
for order in orders: for order in orders:
try: try:
previous_bill = order.bill.latest('-ending_date') previous_bill = order.bill.latest('ending_date')
except ObjectDoesNotExist: except ObjectDoesNotExist:
previous_bill = None previous_bill = None
@ -68,6 +74,10 @@ def generate_bills_for(year, month, user, allowed_delay):
for order in unpaid_orders: for order in unpaid_orders:
order.bill.add(next_bill) order.bill.add(next_bill)
# TODO: use logger.
print("Generated bill {} (amount: {}) for user {}."
.format(next_bill.uuid, next_bill.total, user))
return next_bill return next_bill
# Return None if no bill was created. # Return None if no bill was created.

View file

@ -1,4 +1,5 @@
from django.db import models from django.db import models
from functools import reduce
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -41,8 +42,8 @@ class Bill(models.Model):
@property @property
def total(self): def total(self):
#return helpers.sum_amounts(self.entries) orders = Order.objects.filter(bill=self)
pass return reduce(lambda acc, order: acc + order.amount, orders, 0)
class BillEntry(): class BillEntry():
start_date = timezone.now() start_date = timezone.now()
@ -95,12 +96,14 @@ class Order(models.Model):
default = RecurringPeriod.PER_MONTH) default = RecurringPeriod.PER_MONTH)
# def amount(self): @property
def amount(self):
# amount = recurring_price # amount = recurring_price
# if recurring and first_month: # if recurring and first_month:
# amount += one_time_price # amount += one_time_price
# return amount # you get the picture amount=1
return amount
class PaymentMethod(models.Model): class PaymentMethod(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)