feat(abonnement): prix + bouton Configurer sur /compte/abonnement (#109)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,13 @@ def _csrf_input():
|
|||||||
return dcc.Input(type="hidden", name="csrf_token", value=generate_csrf())
|
return dcc.Input(type="hidden", name="csrf_token", value=generate_csrf())
|
||||||
|
|
||||||
|
|
||||||
|
def _price_text(meta: dict) -> str | None:
|
||||||
|
ht = meta.get("prix_ht")
|
||||||
|
if ht is None:
|
||||||
|
return None
|
||||||
|
return f"{ht} € HT / mois ({round(ht * 1.2, 2):g} € TTC)"
|
||||||
|
|
||||||
|
|
||||||
def _reabo_button(has_used_trial: bool):
|
def _reabo_button(has_used_trial: bool):
|
||||||
label = "Me réabonner" if has_used_trial else "M'abonner"
|
label = "Me réabonner" if has_used_trial else "M'abonner"
|
||||||
return html.Div(
|
return html.Div(
|
||||||
@@ -43,7 +50,10 @@ def _reabo_button(has_used_trial: bool):
|
|||||||
def _active_view(row):
|
def _active_view(row):
|
||||||
meta = plans.plan_meta(row["plan"]) or {"label": row["plan"]}
|
meta = plans.plan_meta(row["plan"]) or {"label": row["plan"]}
|
||||||
end = format_date_french(row["current_period_end"])
|
end = format_date_french(row["current_period_end"])
|
||||||
blocks = [html.H3(meta["label"], className="mb-3")]
|
blocks = [html.H3(meta["label"], className="mb-1")]
|
||||||
|
price = _price_text(meta)
|
||||||
|
if price:
|
||||||
|
blocks.append(html.P(price, className="text-muted mb-3"))
|
||||||
|
|
||||||
if row["status"] == "pending":
|
if row["status"] == "pending":
|
||||||
blocks.extend(
|
blocks.extend(
|
||||||
@@ -82,6 +92,15 @@ def _active_view(row):
|
|||||||
elif row["status"] == "active":
|
elif row["status"] == "active":
|
||||||
blocks.append(html.P(f"Prochaine facturation : {end}"))
|
blocks.append(html.P(f"Prochaine facturation : {end}"))
|
||||||
|
|
||||||
|
if row["status"] in ("pending", "trial", "active"):
|
||||||
|
blocks.append(
|
||||||
|
html.A(
|
||||||
|
"Configurer mon abonnement",
|
||||||
|
href="/compte/abonnement/mes-infos",
|
||||||
|
className="btn btn-outline-primary mt-3 me-2",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if row["status"] in ("trial", "active"):
|
if row["status"] in ("trial", "active"):
|
||||||
blocks.append(
|
blocks.append(
|
||||||
html.Form(
|
html.Form(
|
||||||
@@ -179,6 +198,8 @@ def _feedback(query):
|
|||||||
"Une erreur est survenue avec le service de paiement.", color="primary"
|
"Une erreur est survenue avec le service de paiement.", color="primary"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if query.get("maj") == "succes":
|
||||||
|
out.append(dbc.Alert("Votre abonnement a été mis à jour.", color="success"))
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -126,3 +126,60 @@ def test_feedback_carte_annule():
|
|||||||
|
|
||||||
text = str(compte_abonnement._feedback({"carte": "annule"}))
|
text = str(compte_abonnement._feedback({"carte": "annule"}))
|
||||||
assert "Modification annulée." in text
|
assert "Modification annulée." in text
|
||||||
|
|
||||||
|
|
||||||
|
def test_price_text_rounds_ttc():
|
||||||
|
from src.pages.compte import abonnement as compte_abonnement
|
||||||
|
|
||||||
|
assert compte_abonnement._price_text({"prix_ht": 20}) == "20 € HT / mois (24 € TTC)"
|
||||||
|
assert compte_abonnement._price_text({"prix_ht": 50}) == "50 € HT / mois (60 € TTC)"
|
||||||
|
assert compte_abonnement._price_text({"label": "x"}) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_active_view_shows_price():
|
||||||
|
from src.pages.compte import abonnement as compte_abonnement
|
||||||
|
|
||||||
|
row = {
|
||||||
|
"plan": "simple",
|
||||||
|
"status": "active",
|
||||||
|
"current_period_end": "2099-01-01T00:00:00+00:00",
|
||||||
|
}
|
||||||
|
assert "24 € TTC" in str(compte_abonnement._active_view(row))
|
||||||
|
|
||||||
|
|
||||||
|
def test_active_view_shows_configure_button_for_active():
|
||||||
|
from src.pages.compte import abonnement as compte_abonnement
|
||||||
|
|
||||||
|
row = {
|
||||||
|
"plan": "simple",
|
||||||
|
"status": "active",
|
||||||
|
"current_period_end": "2099-01-01T00:00:00+00:00",
|
||||||
|
}
|
||||||
|
text = str(compte_abonnement._active_view(row))
|
||||||
|
assert "Configurer mon abonnement" in text
|
||||||
|
assert "href='/compte/abonnement/mes-infos'" in text
|
||||||
|
|
||||||
|
|
||||||
|
def test_active_view_shows_configure_button_for_pending():
|
||||||
|
from src.pages.compte import abonnement as compte_abonnement
|
||||||
|
|
||||||
|
row = {"plan": "simple", "status": "pending", "current_period_end": None}
|
||||||
|
assert "Configurer mon abonnement" in str(compte_abonnement._active_view(row))
|
||||||
|
|
||||||
|
|
||||||
|
def test_active_view_hides_configure_button_for_cancelled():
|
||||||
|
from src.pages.compte import abonnement as compte_abonnement
|
||||||
|
|
||||||
|
row = {
|
||||||
|
"plan": "simple",
|
||||||
|
"status": "cancelled",
|
||||||
|
"current_period_end": "2099-01-01T00:00:00+00:00",
|
||||||
|
}
|
||||||
|
assert "Configurer mon abonnement" not in str(compte_abonnement._active_view(row))
|
||||||
|
|
||||||
|
|
||||||
|
def test_feedback_maj_succes():
|
||||||
|
from src.pages.compte import abonnement as compte_abonnement
|
||||||
|
|
||||||
|
text = str(compte_abonnement._feedback({"maj": "succes"}))
|
||||||
|
assert "Votre abonnement a été mis à jour." in text
|
||||||
|
|||||||
Reference in New Issue
Block a user