Skip to content

Commit b499fb2

Browse files
committed
feat(invoice): separate date of taxable supply
Needed for accounting reasons.
1 parent 70ca730 commit b499fb2

File tree

6 files changed

+76
-2
lines changed

6 files changed

+76
-2
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Generated by Django 5.2.8 on 2025-12-10 14:44
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("invoices", "0020_invoice_customer_note"),
9+
]
10+
11+
operations = [
12+
migrations.AddField(
13+
model_name="invoice",
14+
name="tax_date",
15+
field=models.DateField(
16+
blank=True,
17+
help_text="Date of taxable supply, keep blank for issue date",
18+
null=True,
19+
),
20+
),
21+
]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Generated by Django 5.2.8 on 2025-12-10 14:45
2+
3+
from django.db import migrations
4+
from django.db.models import F
5+
6+
7+
def migrate(apps, schema_editor) -> None:
8+
Invoice = apps.get_model("invoices", "Invoice")
9+
Invoice.objects.filter(tax_date=None).update(tax_date=F("issue_date"))
10+
11+
12+
class Migration(migrations.Migration):
13+
dependencies = [
14+
("invoices", "0021_invoice_tax_date"),
15+
]
16+
17+
operations = [
18+
migrations.RunPython(migrate, migrations.RunPython.noop, elidable=True),
19+
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Generated by Django 5.2.8 on 2025-12-10 14:55
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("invoices", "0022_set_tax_date"),
9+
]
10+
11+
operations = [
12+
migrations.AlterField(
13+
model_name="invoice",
14+
name="tax_date",
15+
field=models.DateField(
16+
blank=True,
17+
help_text="Date of taxable supply, keep blank for issue date",
18+
),
19+
),
20+
]

weblate_web/invoices/models.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ class Invoice(models.Model): # noqa: PLR0904
285285
blank=True,
286286
help_text="Due date / Quote validity, keep blank unless specific terms are needed",
287287
)
288+
tax_date = models.DateField(
289+
blank=True,
290+
help_text="Date of taxable supply, keep blank for issue date",
291+
)
288292

289293
kind = models.IntegerField(choices=InvoiceKind)
290294
category = models.IntegerField(
@@ -355,6 +359,9 @@ def save( # type: ignore[override]
355359
if self.extra is None:
356360
self.extra = {}
357361
extra_fields: list[str] = []
362+
if not self.tax_date:
363+
self.tax_date = self.issue_date
364+
extra_fields.append("tax_date")
358365
if not self.due_date:
359366
self.due_date = self.issue_date + datetime.timedelta(
360367
days=self.get_due_delta()
@@ -699,6 +706,7 @@ def duplicate( # noqa: PLR0913
699706
extra: dict[str, int] | None = None,
700707
customer_reference: str | None = None,
701708
customer_note: str | None = None,
709+
tax_date: datetime.date | None = None,
702710
) -> Invoice:
703711
"""Create a final invoice from draft/proforma upon payment."""
704712
invoice = Invoice.objects.create(
@@ -710,6 +718,7 @@ def duplicate( # noqa: PLR0913
710718
discount=self.discount,
711719
vat_rate=self.vat_rate,
712720
currency=self.currency,
721+
tax_date=cast("datetime.date", tax_date),
713722
parent=self,
714723
prepaid=prepaid,
715724
extra=extra if extra is not None else self.extra,

weblate_web/invoices/templates/invoice-template.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ <h2>Issued by</h2>
247247
<th>Contact</th>
248248
</tr>
249249
<tr>
250-
<td>{{ invoice.issue_date|date }}</td>
250+
<td>{{ invoice.tax_date|date }}</td>
251251
<td>21668027</td>
252252
<td>Michal Čihař</td>
253253
<td>C 52324/KSUL Krajský soud v Ústí nad Labem</td>

weblate_web/payments/backends.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ def generate_invoice(self, *, proforma: bool = False) -> None:
386386
invoice = self.payment.draft_invoice.duplicate(
387387
kind=invoice_kind,
388388
prepaid=not proforma,
389+
tax_date=self.payment.created,
389390
)
390391
else:
391392
category = InvoiceCategory.HOSTING
@@ -396,6 +397,7 @@ def generate_invoice(self, *, proforma: bool = False) -> None:
396397
kind=invoice_kind,
397398
customer=self.payment.customer,
398399
vat_rate=self.payment.customer.vat_rate,
400+
tax_date=self.payment.created,
399401
currency=Currency.EUR,
400402
prepaid=not proforma,
401403
category=category,
@@ -536,7 +538,7 @@ def get_instructions(self) -> list[tuple[StrOrPromise, str]]:
536538
return instructions
537539

538540
@classmethod
539-
def fetch_payments(cls, from_date: str | None = None) -> None: # noqa: C901, PLR0915
541+
def fetch_payments(cls, from_date: str | None = None) -> None: # noqa: C901, PLR0915, PLR0912
540542
from weblate_web.invoices.models import Invoice, InvoiceKind # noqa: PLC0415
541543

542544
tokens: list[str]
@@ -623,6 +625,9 @@ def fetch_payments(cls, from_date: str | None = None) -> None: # noqa: C901, PL
623625
print(f"{invoice.number}: received payment")
624626
# Instantionate backend (does SELECT FOR UPDATE)
625627
backend = payment.get_payment_backend()
628+
# Sync payment date with the actual payment
629+
if backend.payment.created.date() != entry["date"]:
630+
backend.payment.created = entry["date"]
626631
# Store transaction details
627632
backend.payment.details["transaction"] = entry
628633
backend.success()

0 commit comments

Comments
 (0)