Add billables to invoice model
Calculate next invoicing date for billables
This commit is contained in:
parent
fa93056f0d
commit
df85d23295
2 changed files with 28 additions and 1 deletions
|
@ -1,9 +1,14 @@
|
||||||
from django.db.models import IntegerChoices, Model, ForeignKey, CASCADE, TextField, PositiveIntegerField, BooleanField, DateField
|
from django.db.models import IntegerChoices, Model, ForeignKey, CASCADE, TextField, PositiveIntegerField, BooleanField, DateField
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from core.models.profiles import ClientProfile
|
from core.models.profiles import ClientProfile
|
||||||
from core.models.brands import Brand
|
from core.models.brands import Brand
|
||||||
from core.fields.base import LongCharField
|
from core.fields.base import LongCharField
|
||||||
from core.fields.numbers import CostField
|
from core.fields.numbers import CostField
|
||||||
|
from core.models.invoices import InvoiceItem, Invoice
|
||||||
|
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
|
|
||||||
class ActionChoices(IntegerChoices):
|
class ActionChoices(IntegerChoices):
|
||||||
WAIT = 0, "Do not invoice for now"
|
WAIT = 0, "Do not invoice for now"
|
||||||
|
@ -11,12 +16,14 @@ class ActionChoices(IntegerChoices):
|
||||||
CRON = 2, "Invoice at next cron run"
|
CRON = 2, "Invoice at next cron run"
|
||||||
DATE = 3, "Invoice at date"
|
DATE = 3, "Invoice at date"
|
||||||
|
|
||||||
|
|
||||||
class CycleChoices(IntegerChoices):
|
class CycleChoices(IntegerChoices):
|
||||||
DAYS = 0, "Days"
|
DAYS = 0, "Days"
|
||||||
WEEKS = 1, "Weeks"
|
WEEKS = 1, "Weeks"
|
||||||
MONTHS = 2, "Months"
|
MONTHS = 2, "Months"
|
||||||
YEARS = 3, "Years"
|
YEARS = 3, "Years"
|
||||||
|
|
||||||
|
|
||||||
class Billable(Model):
|
class Billable(Model):
|
||||||
client = ForeignKey(ClientProfile, on_delete=CASCADE)
|
client = ForeignKey(ClientProfile, on_delete=CASCADE)
|
||||||
brand = ForeignKey(Brand, on_delete=CASCADE)
|
brand = ForeignKey(Brand, on_delete=CASCADE)
|
||||||
|
@ -29,3 +36,21 @@ class Billable(Model):
|
||||||
date = DateField(null=True)
|
date = DateField(null=True)
|
||||||
recur_cycle = PositiveIntegerField(choices=CycleChoices.choices, null=True)
|
recur_cycle = PositiveIntegerField(choices=CycleChoices.choices, null=True)
|
||||||
recur_count = PositiveIntegerField(null=True)
|
recur_count = PositiveIntegerField(null=True)
|
||||||
|
|
||||||
|
def next_invoicing(self):
|
||||||
|
try:
|
||||||
|
invoiceitems = InvoiceItem.objects.filter(billable=self)
|
||||||
|
|
||||||
|
if not 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:
|
||||||
|
return self.date
|
||||||
|
|
|
@ -5,6 +5,7 @@ from core.fields.numbers import CostField
|
||||||
from core.models.services import Service
|
from core.models.services import Service
|
||||||
from core.models.profiles import ClientProfile
|
from core.models.profiles import ClientProfile
|
||||||
from core.models.local import Currency
|
from core.models.local import Currency
|
||||||
|
from core.models.billable import Billable
|
||||||
|
|
||||||
class Invoice(Model):
|
class Invoice(Model):
|
||||||
client = ForeignKey(ClientProfile, on_delete=CASCADE)
|
client = ForeignKey(ClientProfile, on_delete=CASCADE)
|
||||||
|
@ -22,4 +23,5 @@ class InvoiceItem(Model):
|
||||||
price = CostField()
|
price = CostField()
|
||||||
discount = CostField()
|
discount = CostField()
|
||||||
taxable = BooleanField()
|
taxable = BooleanField()
|
||||||
service = ForeignKey(Service, on_delete=SET_NULL, null=True)
|
service = ForeignKey(Service, on_delete=SET_NULL, null=True)
|
||||||
|
billable = ForeignKey(Billable, on_delete=SET_NULL, null=True)
|
Loading…
Reference in a new issue