mirror of
https://github.com/ae-utbm/sith.git
synced 2025-04-29 12:56:47 +00:00
Rename makecommand to checkout
This commit is contained in:
parent
262ed7eb4c
commit
bc99390b25
@ -32,48 +32,39 @@ susnommés afin de comprendre comment celui-ci marche.
|
||||
|
||||
Cette application contient les vues suivantes :
|
||||
|
||||
- `eboutic_main` (GET) : la vue retournant la page principale de la boutique en ligne.
|
||||
- `EbouticMainView` (GET/POST) : la vue retournant la page principale de la boutique en ligne.
|
||||
Cette vue effectue un filtrage des produits à montrer à l'utilisateur en
|
||||
fonction de ce qu'il a le droit d'acheter.
|
||||
Si cette vue est appelée lors d'une redirection parce qu'une erreur
|
||||
est survenue au cours de la navigation sur la boutique, il est possible
|
||||
de donner les messages d'erreur à donner à l'utilisateur dans la session
|
||||
avec la clef ``"errors"``.
|
||||
Elle est en charge de récupérer le formulaire de création d'un panier et
|
||||
redirige alors vers la vue de checkout.
|
||||
- ``payment_result`` (GET) : retourne une page assez simple disant à l'utilisateur
|
||||
si son paiement a échoué ou réussi. Cette vue est appelée par redirection
|
||||
lorsque l'utilisateur paye son panier avec son argent du compte AE.
|
||||
- ``EbouticCommand`` (POST) : traite la soumission d'un panier par l'utilisateur.
|
||||
Lors de l'appel de cette vue, la requête doit contenir un cookie avec l'état
|
||||
du panier à valider. Ce panier doit strictement être de la forme :
|
||||
```
|
||||
[
|
||||
{"id": <int>, "name": <str>, "quantity": <int>, "unit_price": <float>},
|
||||
{"id": <int>, "name": <str>, "quantity": <int>, "unit_price": <float>},
|
||||
<etc.>
|
||||
]
|
||||
```
|
||||
Si le panier est mal formaté ou contient des valeurs invalides,
|
||||
une redirection est faite vers `eboutic_main`.
|
||||
- ``pay_with_sith`` (POST) : paie le panier avec l'argent présent sur le compte
|
||||
- ``EbouticCheckout`` (GET/POST) : Page récapitulant le contenu d'un panier.
|
||||
Permet de sélectionner le moyen de paiement et de mettre à jour ses coordonnées
|
||||
de paiement par carte bancaire.
|
||||
- ``PayWithSith`` (POST) : paie le panier avec l'argent présent sur le compte
|
||||
AE. Redirige vers `payment_result`.
|
||||
- ``ETransactionAutoAnswer`` (GET) : vue destinée à communiquer avec le service
|
||||
de paiement bancaire pour valider ou non le paiement de l'utilisateur.
|
||||
- ``BillingInfoFormFragment`` (GET/POST) : vue destinée à gérer les informations de paiement de l'utilisateur courant.
|
||||
|
||||
# Les templates
|
||||
|
||||
- ``eboutic_payment_result.jinja`` : très court template contenant juste
|
||||
un message pour dire à l'utilisateur si son achat s'est bien déroulé.
|
||||
Retourné par la vue ``payment_result``.
|
||||
- ``eboutic_makecommand.jinja`` : template contenant un résumé du panier et deux
|
||||
- ``eboutic_checkout.jinja`` : template contenant un résumé du panier et deux
|
||||
boutons, un pour payer avec le site AE et l'autre pour payer par carte bancaire.
|
||||
Retourné par la vue ``EbouticCommand``
|
||||
Retourné par la vue ``EbouticCheckout``
|
||||
- ``eboutic_billing_info.jinja`` : formulaire de modification des coordonnées bancaires.
|
||||
Elle permet également de mettre à jour ses coordonnées de paiement
|
||||
- ``eboutic_main.jinja`` : le plus gros template de cette application. Contient
|
||||
une interface pour que l'utilisateur puisse consulter les produits et remplir
|
||||
son panier. Les opérations de remplissage du panier se font entièrement côté client.
|
||||
À chaque clic pour ajouter ou retirer un élément du panier, le script JS
|
||||
(AlpineJS, plus précisément) édite en même temps un cookie.
|
||||
Au moment de la validation du panier, ce cookie est envoyé au serveur pour
|
||||
vérifier que la commande est valide et payer.
|
||||
(AlpineJS, plus précisément) édite en même temps le localStorage du navigateur.
|
||||
Cette vue fabrique dynamiquement un formulaire qui sera soumis au serveur.
|
||||
|
||||
# Les modèles
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block additional_js %}
|
||||
<script type="module" src="{{ static('bundled/eboutic/makecommand-index.ts') }}"></script>
|
||||
<script type="module" src="{{ static('bundled/eboutic/checkout-index.ts') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
@ -30,10 +30,10 @@
|
||||
{{ form.management_form }}
|
||||
</div>
|
||||
|
||||
{% if form.non_form_errors() %}
|
||||
{% if form.non_form_errors() or form.errors %}
|
||||
<div class="alert alert-red">
|
||||
<div class="alert-main">
|
||||
{% for error in form.non_form_errors() %}
|
||||
{% for error in form.non_form_errors() + form.errors %}
|
||||
<p style="margin: 0">{{ error }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
@ -50,7 +50,7 @@
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<template x-for="(item, index) in Object.values(basket)">
|
||||
<template x-for="(item, index) in Object.values(basket)" :key="item.id">
|
||||
<li class="item-row" x-show="item.quantity > 0">
|
||||
<div class="item-quantity">
|
||||
<i class="fa fa-minus fa-xs" @click="remove(item.id)"></i>
|
||||
@ -94,8 +94,8 @@
|
||||
<i class="fa fa-check"></i>
|
||||
<input type="submit" value="{% trans %}Validate{% endtrans %}"/>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id="catalog">
|
||||
{% if not request.user.date_of_birth %}
|
||||
|
@ -27,8 +27,8 @@ from django.urls import path, register_converter
|
||||
from eboutic.converters import PaymentResultConverter
|
||||
from eboutic.views import (
|
||||
BillingInfoFormFragment,
|
||||
EbouticCommand,
|
||||
EbouticCreateBasket,
|
||||
EbouticCheckout,
|
||||
EbouticMainView,
|
||||
EbouticPayWithSith,
|
||||
EtransactionAutoAnswer,
|
||||
EurokPartnerFragment,
|
||||
@ -39,8 +39,8 @@ register_converter(PaymentResultConverter, "res")
|
||||
|
||||
urlpatterns = [
|
||||
# Subscription views
|
||||
path("", EbouticCreateBasket.as_view(), name="main"),
|
||||
path("command/<int:basket_id>", EbouticCommand.as_view(), name="command"),
|
||||
path("", EbouticMainView.as_view(), name="main"),
|
||||
path("checkout/<int:basket_id>", EbouticCheckout.as_view(), name="checkout"),
|
||||
path("billing-infos/", BillingInfoFormFragment.as_view(), name="billing_infos"),
|
||||
path(
|
||||
"pay/sith/<int:basket_id>", EbouticPayWithSith.as_view(), name="pay_with_sith"
|
||||
|
@ -18,7 +18,6 @@ from __future__ import annotations
|
||||
import base64
|
||||
import contextlib
|
||||
import json
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import sentry_sdk
|
||||
@ -75,7 +74,7 @@ EbouticBasketForm = forms.formset_factory(
|
||||
)
|
||||
|
||||
|
||||
class EbouticCreateBasket(LoginRequiredMixin, FormView):
|
||||
class EbouticMainView(LoginRequiredMixin, FormView):
|
||||
"""Main view of the eboutic application.
|
||||
|
||||
The purchasable products are those of the eboutic which
|
||||
@ -98,6 +97,7 @@ class EbouticCreateBasket(LoginRequiredMixin, FormView):
|
||||
|
||||
def form_valid(self, formset):
|
||||
if len(formset) == 0:
|
||||
formset.errors.append(_("Your basket is empty"))
|
||||
return self.form_invalid(formset)
|
||||
|
||||
with transaction.atomic():
|
||||
@ -110,7 +110,7 @@ class EbouticCreateBasket(LoginRequiredMixin, FormView):
|
||||
return super().form_valid(formset)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse("eboutic:command", kwargs={"basket_id": self.basket.id})
|
||||
return reverse("eboutic:checkout", kwargs={"basket_id": self.basket.id})
|
||||
|
||||
@cached_property
|
||||
def products(self) -> list[Product]:
|
||||
@ -196,11 +196,11 @@ class BillingInfoFormFragment(
|
||||
return self.request.path
|
||||
|
||||
|
||||
class EbouticCommand(CanViewMixin, UseFragmentsMixin, DetailView):
|
||||
class EbouticCheckout(CanViewMixin, UseFragmentsMixin, DetailView):
|
||||
model = Basket
|
||||
pk_url_kwarg = "basket_id"
|
||||
context_object_name = "basket"
|
||||
template_name = "eboutic/eboutic_makecommand.jinja"
|
||||
template_name = "eboutic/eboutic_checkout.jinja"
|
||||
fragments = {
|
||||
"billing_infos_form": BillingInfoFormFragment,
|
||||
}
|
||||
@ -247,13 +247,8 @@ class EbouticPayWithSith(CanViewMixin, SingleObjectMixin, View):
|
||||
basket.delete()
|
||||
return redirect("eboutic:payment_result", "success")
|
||||
except DatabaseError as e:
|
||||
with sentry_sdk.push_scope() as scope:
|
||||
scope.user = {"username": request.user.username}
|
||||
scope.set_extra("someVariable", e.__repr__())
|
||||
sentry_sdk.capture_message(
|
||||
f"Erreur le {datetime.now()} dans eboutic.pay_with_sith"
|
||||
)
|
||||
return redirect("eboutic:payment_result", "failure")
|
||||
sentry_sdk.capture_exception(e)
|
||||
return redirect("eboutic:payment_result", "failure")
|
||||
|
||||
|
||||
class EtransactionAutoAnswer(View):
|
||||
|
Loading…
x
Reference in New Issue
Block a user