use new price system in the eboutic

This commit is contained in:
imperosol
2026-03-02 15:47:42 +01:00
parent 85f1a0b9cb
commit a019707d4a
4 changed files with 97 additions and 95 deletions

View File

@@ -17,6 +17,7 @@ from __future__ import annotations
import base64
import contextlib
import itertools
import json
from typing import TYPE_CHECKING
@@ -48,11 +49,11 @@ from django_countries.fields import Country
from core.auth.mixins import CanViewMixin
from core.views.mixins import FragmentMixin, UseFragmentsMixin
from counter.forms import BaseBasketForm, BasketProductForm, BillingInfoForm
from counter.forms import BaseBasketForm, BasketItemForm, BillingInfoForm
from counter.models import (
BillingInfo,
Customer,
Product,
Price,
Refilling,
Selling,
get_eboutic,
@@ -63,7 +64,7 @@ from eboutic.models import (
BillingInfoState,
Invoice,
InvoiceItem,
get_eboutic_products,
get_eboutic_prices,
)
if TYPE_CHECKING:
@@ -78,7 +79,7 @@ class BaseEbouticBasketForm(BaseBasketForm):
EbouticBasketForm = forms.formset_factory(
BasketProductForm, formset=BaseEbouticBasketForm, absolute_max=None, min_num=1
BasketItemForm, formset=BaseEbouticBasketForm, absolute_max=None, min_num=1
)
@@ -88,7 +89,6 @@ class EbouticMainView(LoginRequiredMixin, FormView):
The purchasable products are those of the eboutic which
belong to a category of products of a product category
(orphan products are inaccessible).
"""
template_name = "eboutic/eboutic_main.jinja"
@@ -99,7 +99,7 @@ class EbouticMainView(LoginRequiredMixin, FormView):
kwargs["form_kwargs"] = {
"customer": self.customer,
"counter": get_eboutic(),
"allowed_products": {product.id: product for product in self.products},
"allowed_prices": {price.id: price for price in self.prices},
}
return kwargs
@@ -110,19 +110,22 @@ class EbouticMainView(LoginRequiredMixin, FormView):
with transaction.atomic():
self.basket = Basket.objects.create(user=self.request.user)
for form in formset:
BasketItem.from_product(
form.product, form.cleaned_data["quantity"], self.basket
).save()
self.basket.save()
BasketItem.objects.bulk_create(
[
BasketItem.from_price(
form.price, form.cleaned_data["quantity"], self.basket
)
for form in formset
]
)
return super().form_valid(formset)
def get_success_url(self):
return reverse("eboutic:checkout", kwargs={"basket_id": self.basket.id})
@cached_property
def products(self) -> list[Product]:
return get_eboutic_products(self.request.user)
def prices(self) -> list[Price]:
return get_eboutic_prices(self.request.user)
@cached_property
def customer(self) -> Customer:
@@ -130,7 +133,12 @@ class EbouticMainView(LoginRequiredMixin, FormView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["products"] = self.products
context["categories"] = [
list(i[1])
for i in itertools.groupby(
self.prices, key=lambda p: p.product.product_type_id
)
]
context["customer_amount"] = self.request.user.account_balance
purchases = (
@@ -267,11 +275,8 @@ class EbouticPayWithSith(CanViewMixin, SingleObjectMixin, View):
def post(self, request, *args, **kwargs):
basket = self.get_object()
refilling = settings.SITH_COUNTER_PRODUCTTYPE_REFILLING
if basket.items.filter(type_id=refilling).exists():
messages.error(
self.request,
_("You can't buy a refilling with sith money"),
)
if basket.items.filter(product__product_type_id=refilling).exists():
messages.error(self.request, _("You can't buy a refilling with sith money"))
return redirect("eboutic:payment_result", "failure")
eboutic = get_eboutic()
@@ -326,22 +331,23 @@ class EtransactionAutoAnswer(View):
raise SuspiciousOperation(
"Basket total and amount do not match"
)
i = Invoice()
i.user = b.user
i.payment_method = "CARD"
i.save()
for it in b.items.all():
InvoiceItem(
invoice=i,
product_id=it.product_id,
product_name=it.product_name,
type_id=it.type_id,
product_unit_price=it.product_unit_price,
quantity=it.quantity,
).save()
i = Invoice.objects.create(user=b.user)
InvoiceItem.objects.bulk_create(
[
InvoiceItem(
invoice=i,
product_id=item.product_id,
label=item.label,
unit_price=item.unit_price,
quantity=item.quantity,
)
for item in b.items.all()
]
)
i.validate()
b.delete()
except Exception as e:
sentry_sdk.capture_exception(e)
return HttpResponse(
"Basket processing failed with error: " + repr(e), status=500
)