Skip to content

Commit 7222805

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

File tree

6 files changed

+75
-2
lines changed

6 files changed

+75
-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: 8 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,8 @@ 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
358364
if not self.due_date:
359365
self.due_date = self.issue_date + datetime.timedelta(
360366
days=self.get_due_delta()
@@ -699,6 +705,7 @@ def duplicate( # noqa: PLR0913
699705
extra: dict[str, int] | None = None,
700706
customer_reference: str | None = None,
701707
customer_note: str | None = None,
708+
tax_date: datetime.date | None = None,
702709
) -> Invoice:
703710
"""Create a final invoice from draft/proforma upon payment."""
704711
invoice = Invoice.objects.create(
@@ -710,6 +717,7 @@ def duplicate( # noqa: PLR0913
710717
discount=self.discount,
711718
vat_rate=self.vat_rate,
712719
currency=self.currency,
720+
tax_date=tax_date,
713721
parent=self,
714722
prepaid=prepaid,
715723
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)