Skip to content

Commit

Permalink
feat: use draft invoices for donation
Browse files Browse the repository at this point in the history
  • Loading branch information
nijel committed Oct 23, 2024
1 parent 16edbb0 commit 5f7637d
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 12 deletions.
29 changes: 26 additions & 3 deletions weblate_web/invoices/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import datetime
from decimal import Decimal
from pathlib import Path
from typing import TYPE_CHECKING

from django.conf import settings
from django.contrib.staticfiles import finders
Expand All @@ -35,11 +36,20 @@
from weasyprint import CSS, HTML
from weasyprint.text.fonts import FontConfiguration

if TYPE_CHECKING:
from weblate_web.payments.models import Payment

INVOICES_URL = "invoices:"
STATIC_URL = "static:"
TEMPLATES_PATH = Path(__file__).parent / "templates"


def round_decimal(num: Decimal) -> Decimal:
if num % Decimal("0.01"):
return round(num, 3)
return num


def url_fetcher(url: str) -> dict[str, str | bytes]:
path_obj: Path
result: dict[str, str | bytes]
Expand Down Expand Up @@ -211,7 +221,7 @@ def display_total_discount(self) -> str:

@cached_property
def total_amount_no_vat(self) -> Decimal:
return self.total_items_amount + self.total_discount
return round_decimal(self.total_items_amount + self.total_discount)

@property
def total_amount_no_vat_czk(self) -> Decimal:
Expand All @@ -225,7 +235,7 @@ def display_total_amount_no_vat(self) -> str:
def total_vat(self) -> Decimal:
if not self.vat_rate:
return Decimal(0)
return self.total_amount_no_vat * self.vat_rate / 100
return round_decimal(self.total_amount_no_vat * self.vat_rate / 100)

@property
def total_vat_czk(self) -> Decimal:
Expand All @@ -251,6 +261,9 @@ def display_total_amount(self) -> str:
def all_items(self) -> models.QuerySet[InvoiceItem]:
return self.invoiceitem_set.order_by("id")

def get_description(self) -> str:
return self.all_items[0].description

def render_html(self) -> str:
with override("en_GB"):
return render_to_string(
Expand Down Expand Up @@ -322,7 +335,7 @@ def add_amounts(root, in_czk: bool = False):
output = etree.SubElement(invoices, "FaktVyd")
add_element(output, "Doklad", self.number)
add_element(output, "CisRada", self.kind)
add_element(output, "Popis", self.all_items[0].description)
add_element(output, "Popis", self.get_description())
add_element(output, "Vystaveno", self.issue_date.isoformat())
add_element(output, "DatUcPr", self.issue_date.isoformat())
add_element(output, "PlnenoDPH", self.issue_date.isoformat())
Expand Down Expand Up @@ -456,6 +469,16 @@ def finalize(
)
return invoice

def create_payment(self, recurring: str, extra: dict) -> Payment:
return self.draft_payment_set.create(

Check failure on line 473 in weblate_web/invoices/models.py

View workflow job for this annotation

GitHub Actions / mypy

Incompatible type for "amount" of "Payment" (got "Decimal", expected "float | int | str | Combinable")

Check failure on line 473 in weblate_web/invoices/models.py

View workflow job for this annotation

GitHub Actions / mypy

Incompatible type for "amount" of "Payment" (got "Decimal", expected "float | int | str | Combinable")
amount=self.total_amount,
amount_fixed=True,
description=self.get_description(),
recurring=recurring,
extra=extra,
customer=self.customer,
)


class InvoiceItem(models.Model):
invoice = models.ForeignKey(Invoice, on_delete=models.deletion.CASCADE)
Expand Down
2 changes: 1 addition & 1 deletion weblate_web/test-data/fakturace
1 change: 1 addition & 0 deletions weblate_web/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ def test_donation_workflow_card(self, reward=0):
)
self.assertContains(response, "Please provide your billing")
payment = Payment.objects.all().get()
self.assertEqual(payment.amount, 1000)
self.assertEqual(payment.state, Payment.NEW)
customer_url = reverse("payment-customer", kwargs={"pk": payment.uuid})
payment_url = reverse("payment", kwargs={"pk": payment.uuid})
Expand Down
34 changes: 26 additions & 8 deletions weblate_web/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import json
import random
from decimal import Decimal
from typing import TYPE_CHECKING

import django.views.defaults
Expand Down Expand Up @@ -65,6 +66,12 @@
EditNameForm,
MethodForm,
)
from weblate_web.invoices.models import (
Invoice,
InvoiceCategory,
InvoiceKind,
round_decimal,
)
from weblate_web.models import (
PAYMENTS_ORIGIN,
REWARD_LEVELS,
Expand Down Expand Up @@ -488,11 +495,6 @@ def get_form_kwargs(self):
result["initial"] = self.request.GET
return result

def redirect_payment(self, **kwargs):
kwargs["customer"] = get_customer(self.request)
payment = Payment.objects.create(**kwargs)
return redirect(payment.get_payment_url())

def get_context_data(self, **kwargs):
result = super().get_context_data(**kwargs)
result["reward_levels"] = REWARD_LEVELS
Expand All @@ -507,13 +509,29 @@ def form_valid(self, form):
tmp = Donation(reward=int(data["reward"] or "0"))
with override("en"):
description = tmp.get_payment_description()
return self.redirect_payment(
amount=data["amount"],
amount_fixed=True,
customer = get_customer(self.request)
vat_rate = customer.vat_rate
invoice = Invoice.objects.create(
kind=InvoiceKind.DRAFT,
category=InvoiceCategory.DONATE,
customer=customer,
vat_rate=vat_rate,
)
amount = Decimal(data["amount"])
if vat_rate:
amount = round_decimal(
amount * Decimal(100) / (Decimal(100) + Decimal(vat_rate))
)
invoice.invoiceitem_set.create(
description=description,
unit_price=amount,
)

payment = invoice.create_payment(
recurring=data["recurring"],
extra={"reward": data["reward"]},
)
return redirect(payment.get_payment_url())


@login_required
Expand Down

0 comments on commit 5f7637d

Please sign in to comment.