mirror of
https://github.com/ae-utbm/sith.git
synced 2025-04-29 21:06:45 +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 :
|
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
|
Cette vue effectue un filtrage des produits à montrer à l'utilisateur en
|
||||||
fonction de ce qu'il a le droit d'acheter.
|
fonction de ce qu'il a le droit d'acheter.
|
||||||
Si cette vue est appelée lors d'une redirection parce qu'une erreur
|
Elle est en charge de récupérer le formulaire de création d'un panier et
|
||||||
est survenue au cours de la navigation sur la boutique, il est possible
|
redirige alors vers la vue de checkout.
|
||||||
de donner les messages d'erreur à donner à l'utilisateur dans la session
|
|
||||||
avec la clef ``"errors"``.
|
|
||||||
- ``payment_result`` (GET) : retourne une page assez simple disant à l'utilisateur
|
- ``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
|
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.
|
lorsque l'utilisateur paye son panier avec son argent du compte AE.
|
||||||
- ``EbouticCommand`` (POST) : traite la soumission d'un panier par l'utilisateur.
|
- ``EbouticCheckout`` (GET/POST) : Page récapitulant le contenu d'un panier.
|
||||||
Lors de l'appel de cette vue, la requête doit contenir un cookie avec l'état
|
Permet de sélectionner le moyen de paiement et de mettre à jour ses coordonnées
|
||||||
du panier à valider. Ce panier doit strictement être de la forme :
|
de paiement par carte bancaire.
|
||||||
```
|
- ``PayWithSith`` (POST) : paie le panier avec l'argent présent sur le compte
|
||||||
[
|
|
||||||
{"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
|
|
||||||
AE. Redirige vers `payment_result`.
|
AE. Redirige vers `payment_result`.
|
||||||
- ``ETransactionAutoAnswer`` (GET) : vue destinée à communiquer avec le service
|
- ``ETransactionAutoAnswer`` (GET) : vue destinée à communiquer avec le service
|
||||||
de paiement bancaire pour valider ou non le paiement de l'utilisateur.
|
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
|
# Les templates
|
||||||
|
|
||||||
- ``eboutic_payment_result.jinja`` : très court template contenant juste
|
- ``eboutic_payment_result.jinja`` : très court template contenant juste
|
||||||
un message pour dire à l'utilisateur si son achat s'est bien déroulé.
|
un message pour dire à l'utilisateur si son achat s'est bien déroulé.
|
||||||
Retourné par la vue ``payment_result``.
|
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.
|
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
|
- ``eboutic_main.jinja`` : le plus gros template de cette application. Contient
|
||||||
une interface pour que l'utilisateur puisse consulter les produits et remplir
|
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.
|
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
|
À 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.
|
(AlpineJS, plus précisément) édite en même temps le localStorage du navigateur.
|
||||||
Au moment de la validation du panier, ce cookie est envoyé au serveur pour
|
Cette vue fabrique dynamiquement un formulaire qui sera soumis au serveur.
|
||||||
vérifier que la commande est valide et payer.
|
|
||||||
|
|
||||||
# Les modèles
|
# Les modèles
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block additional_js %}
|
{% 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 %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
@ -30,10 +30,10 @@
|
|||||||
{{ form.management_form }}
|
{{ form.management_form }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if form.non_form_errors() %}
|
{% if form.non_form_errors() or form.errors %}
|
||||||
<div class="alert alert-red">
|
<div class="alert alert-red">
|
||||||
<div class="alert-main">
|
<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>
|
<p style="margin: 0">{{ error }}</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
@ -50,7 +50,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</li>
|
</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">
|
<li class="item-row" x-show="item.quantity > 0">
|
||||||
<div class="item-quantity">
|
<div class="item-quantity">
|
||||||
<i class="fa fa-minus fa-xs" @click="remove(item.id)"></i>
|
<i class="fa fa-minus fa-xs" @click="remove(item.id)"></i>
|
||||||
@ -94,8 +94,8 @@
|
|||||||
<i class="fa fa-check"></i>
|
<i class="fa fa-check"></i>
|
||||||
<input type="submit" value="{% trans %}Validate{% endtrans %}"/>
|
<input type="submit" value="{% trans %}Validate{% endtrans %}"/>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="catalog">
|
<div id="catalog">
|
||||||
{% if not request.user.date_of_birth %}
|
{% 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.converters import PaymentResultConverter
|
||||||
from eboutic.views import (
|
from eboutic.views import (
|
||||||
BillingInfoFormFragment,
|
BillingInfoFormFragment,
|
||||||
EbouticCommand,
|
EbouticCheckout,
|
||||||
EbouticCreateBasket,
|
EbouticMainView,
|
||||||
EbouticPayWithSith,
|
EbouticPayWithSith,
|
||||||
EtransactionAutoAnswer,
|
EtransactionAutoAnswer,
|
||||||
EurokPartnerFragment,
|
EurokPartnerFragment,
|
||||||
@ -39,8 +39,8 @@ register_converter(PaymentResultConverter, "res")
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# Subscription views
|
# Subscription views
|
||||||
path("", EbouticCreateBasket.as_view(), name="main"),
|
path("", EbouticMainView.as_view(), name="main"),
|
||||||
path("command/<int:basket_id>", EbouticCommand.as_view(), name="command"),
|
path("checkout/<int:basket_id>", EbouticCheckout.as_view(), name="checkout"),
|
||||||
path("billing-infos/", BillingInfoFormFragment.as_view(), name="billing_infos"),
|
path("billing-infos/", BillingInfoFormFragment.as_view(), name="billing_infos"),
|
||||||
path(
|
path(
|
||||||
"pay/sith/<int:basket_id>", EbouticPayWithSith.as_view(), name="pay_with_sith"
|
"pay/sith/<int:basket_id>", EbouticPayWithSith.as_view(), name="pay_with_sith"
|
||||||
|
@ -18,7 +18,6 @@ from __future__ import annotations
|
|||||||
import base64
|
import base64
|
||||||
import contextlib
|
import contextlib
|
||||||
import json
|
import json
|
||||||
from datetime import datetime
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import sentry_sdk
|
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.
|
"""Main view of the eboutic application.
|
||||||
|
|
||||||
The purchasable products are those of the eboutic which
|
The purchasable products are those of the eboutic which
|
||||||
@ -98,6 +97,7 @@ class EbouticCreateBasket(LoginRequiredMixin, FormView):
|
|||||||
|
|
||||||
def form_valid(self, formset):
|
def form_valid(self, formset):
|
||||||
if len(formset) == 0:
|
if len(formset) == 0:
|
||||||
|
formset.errors.append(_("Your basket is empty"))
|
||||||
return self.form_invalid(formset)
|
return self.form_invalid(formset)
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
@ -110,7 +110,7 @@ class EbouticCreateBasket(LoginRequiredMixin, FormView):
|
|||||||
return super().form_valid(formset)
|
return super().form_valid(formset)
|
||||||
|
|
||||||
def get_success_url(self):
|
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
|
@cached_property
|
||||||
def products(self) -> list[Product]:
|
def products(self) -> list[Product]:
|
||||||
@ -196,11 +196,11 @@ class BillingInfoFormFragment(
|
|||||||
return self.request.path
|
return self.request.path
|
||||||
|
|
||||||
|
|
||||||
class EbouticCommand(CanViewMixin, UseFragmentsMixin, DetailView):
|
class EbouticCheckout(CanViewMixin, UseFragmentsMixin, DetailView):
|
||||||
model = Basket
|
model = Basket
|
||||||
pk_url_kwarg = "basket_id"
|
pk_url_kwarg = "basket_id"
|
||||||
context_object_name = "basket"
|
context_object_name = "basket"
|
||||||
template_name = "eboutic/eboutic_makecommand.jinja"
|
template_name = "eboutic/eboutic_checkout.jinja"
|
||||||
fragments = {
|
fragments = {
|
||||||
"billing_infos_form": BillingInfoFormFragment,
|
"billing_infos_form": BillingInfoFormFragment,
|
||||||
}
|
}
|
||||||
@ -247,12 +247,7 @@ class EbouticPayWithSith(CanViewMixin, SingleObjectMixin, View):
|
|||||||
basket.delete()
|
basket.delete()
|
||||||
return redirect("eboutic:payment_result", "success")
|
return redirect("eboutic:payment_result", "success")
|
||||||
except DatabaseError as e:
|
except DatabaseError as e:
|
||||||
with sentry_sdk.push_scope() as scope:
|
sentry_sdk.capture_exception(e)
|
||||||
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")
|
return redirect("eboutic:payment_result", "failure")
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user