expephalon/core/mixins/billable.py

47 lines
No EOL
1.7 KiB
Python

from django.db.models import PositiveIntegerField, DateField, IntegerChoices, Model
from dateutil.relativedelta import relativedelta
class ActionChoices(IntegerChoices):
WAIT = 0, "Do not invoice for now"
NEXT = 1, "Add to client's next invoice"
CRON = 2, "Invoice at next cron run"
DATE = 3, "Invoice at date"
class CycleChoices(IntegerChoices):
DAYS = 0, "Days"
WEEKS = 1, "Weeks"
MONTHS = 2, "Months"
YEARS = 3, "Years"
class RecurMixin(Model):
class Meta:
abstract = True
date = DateField()
recur_action = PositiveIntegerField(choices=ActionChoices.choices)
recur_cycle = PositiveIntegerField(choices=CycleChoices.choices)
recur_count = PositiveIntegerField()
def next_invoicing(self):
from core.models.invoices import InvoiceItem, Invoice
if not (self.recur_action == ActionChoices.DATE) or self.recur_cycle:
return False
try:
invoiceitems = InvoiceItem.objects.filter(billable=self)
if invoiceitems and not self.recur_cycle:
return False
invoice = Invoice.objects.filter(invoiceitem_set__contains=invoiceitems).latest("created")
delta = relativedelta(days=self.recur_count if self.recur_cycle == CycleChoices.DAYS else 0,
weeks=self.recur_count if self.recur_cycle == CycleChoices.WEEKS else 0,
months=self.recur_count if self.recur_cycle == CycleChoices.MONTHS else 0,
years=self.recur_count if self.recur_cycle == CycleChoices.YEARS else 0)
return invoice.created + delta
except InvoiceItem.DoesNotExist:
return self.date