Skip to content

Commit

Permalink
fix(invoice): store full invoice number in a database
Browse files Browse the repository at this point in the history
This is needed for lookups.
  • Loading branch information
nijel committed Oct 18, 2024
1 parent f38b049 commit 973c090
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 11 deletions.
46 changes: 46 additions & 0 deletions weblate_web/invoices/migrations/0004_invoice_number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Generated by Django 5.1.2 on 2024-10-18 10:58

import django.db.models.expressions
import django.db.models.functions.comparison
import django.db.models.functions.datetime
import django.db.models.functions.text
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("invoices", "0003_alter_invoice_kind"),
]

operations = [
migrations.AddField(
model_name="invoice",
name="number",
field=models.GeneratedField(
db_persist=True,
expression=django.db.models.functions.text.Concat(
django.db.models.functions.comparison.Cast(
"kind", models.CharField()
),
django.db.models.functions.comparison.Cast(
django.db.models.expressions.CombinedExpression(
django.db.models.functions.datetime.Extract(
"issue_date", "year"
),
"%%",
models.Value(2000),
),
models.CharField(),
),
django.db.models.functions.text.LPad(
django.db.models.functions.comparison.Cast(
"sequence", models.CharField()
),
6,
models.Value("0"),
),
),
output_field=models.CharField(max_length=20),
),
),
]
29 changes: 18 additions & 11 deletions weblate_web/invoices/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from django.conf import settings
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models.functions import Extract
from django.db.models.functions import Cast, Concat, Extract, LPad
from django.template.loader import render_to_string
from django.utils.functional import cached_property
from django.utils.translation import override
Expand Down Expand Up @@ -82,6 +82,15 @@ def display_percents(self) -> str:

class Invoice(models.Model):
sequence = models.IntegerField(editable=False)
number = models.GeneratedField(
expression=Concat(
Cast("kind", models.CharField()),
Cast(Extract("issue_date", "year") % 2000, models.CharField()),
LPad(Cast("sequence", models.CharField()), 6, models.Value("0")),
),
output_field=models.CharField(max_length=20),
db_persist=True,
)
issue_date = models.DateField(default=datetime.date.today)
due_date = models.DateField(blank=True)
kind = models.IntegerField(choices=InvoiceKindChoices)
Expand Down Expand Up @@ -115,15 +124,15 @@ def __str__(self) -> str:
def save(
self,
*,
force_insert=False,
force_update=False,
force_insert: bool = False,
force_update: bool = False,
using=None,
update_fields=None,
):
extra_fields: list[str] = []
if not self.due_date:
self.due_date = self.issue_date + datetime.timedelta(days=14)
if update_fields is not None:
update_fields = ("due_date", *update_fields)
extra_fields.append("due_date")
if not self.sequence:
try:
self.sequence = (
Expand All @@ -136,19 +145,17 @@ def save(
)
except IndexError:
self.sequence = 1
if update_fields is not None:
update_fields = ("sequence", *update_fields)
extra_fields.append("sequence")
if extra_fields and update_fields is not None:
update_fields = tuple(set(update_fields).union(extra_fields))

super().save(
force_insert=force_insert,
force_update=force_update,
using=using,
update_fields=update_fields,
)

@property
def number(self) -> str:
return f"{self.kind}{self.issue_date.year % 2000}{self.sequence:05d}"

def render_amount(self, amount: int | Decimal) -> str:
if self.currency == CurrencyChoices.EUR:
return f"€{amount}"
Expand Down

0 comments on commit 973c090

Please sign in to comment.