parent
ca9c37f2c8
commit
027ce2d9bc
@ -0,0 +1,5 @@ |
|||||||
|
from django import forms |
||||||
|
|
||||||
|
class GuestCheckoutForm(forms.Form): |
||||||
|
email = forms.EmailField(required=True) |
||||||
|
phone = forms.CharField(max_length=20, required=True) |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
# Generated by Django 4.2.11 on 2025-03-18 14:24 |
||||||
|
|
||||||
|
from django.db import migrations |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('shop', '0007_product_cut'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterModelOptions( |
||||||
|
name='product', |
||||||
|
options={'ordering': ['ordering_value', 'cut']}, |
||||||
|
), |
||||||
|
migrations.RenameField( |
||||||
|
model_name='product', |
||||||
|
old_name='order', |
||||||
|
new_name='ordering_value', |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,38 @@ |
|||||||
|
# Generated by Django 4.2.11 on 2025-03-18 14:36 |
||||||
|
|
||||||
|
from django.conf import settings |
||||||
|
from django.db import migrations, models |
||||||
|
import django.db.models.deletion |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
||||||
|
('shop', '0008_alter_product_options_and_more'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.CreateModel( |
||||||
|
name='Order', |
||||||
|
fields=[ |
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||||
|
('date_ordered', models.DateTimeField(auto_now_add=True)), |
||||||
|
('status', models.CharField(choices=[('PENDING', 'Pending'), ('PAID', 'Paid'), ('SHIPPED', 'Shipped'), ('DELIVERED', 'Delivered'), ('CANCELED', 'Canceled')], default='PENDING', max_length=20)), |
||||||
|
('total_price', models.DecimalField(decimal_places=2, default=0.0, max_digits=10)), |
||||||
|
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), |
||||||
|
], |
||||||
|
), |
||||||
|
migrations.CreateModel( |
||||||
|
name='OrderItem', |
||||||
|
fields=[ |
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||||
|
('quantity', models.PositiveIntegerField(default=1)), |
||||||
|
('price', models.DecimalField(decimal_places=2, max_digits=10)), |
||||||
|
('color', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='shop.color')), |
||||||
|
('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='shop.order')), |
||||||
|
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.product')), |
||||||
|
('size', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='shop.size')), |
||||||
|
], |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,21 @@ |
|||||||
|
# Generated by Django 4.2.11 on 2025-03-18 14:50 |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('shop', '0009_order_orderitem'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.CreateModel( |
||||||
|
name='GuestUser', |
||||||
|
fields=[ |
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||||
|
('email', models.EmailField(max_length=254)), |
||||||
|
('phone', models.CharField(max_length=20)), |
||||||
|
], |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,19 @@ |
|||||||
|
# Generated by Django 4.2.11 on 2025-03-18 17:59 |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
import django.db.models.deletion |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('shop', '0010_guestuser'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='order', |
||||||
|
name='guest_user', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='shop.guestuser'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,47 @@ |
|||||||
|
{% extends 'tournaments/base.html' %} |
||||||
|
|
||||||
|
{% block head_title %}La boutique{% endblock %} |
||||||
|
{% block first_title %}La boutique Padel Club{% endblock %} |
||||||
|
{% block second_title %}Validation de la commande{% endblock %} |
||||||
|
|
||||||
|
{% block content %} |
||||||
|
|
||||||
|
<nav class="margin10"> |
||||||
|
<a href="{% url 'shop:product_list' %}">La Boutique</a> |
||||||
|
<a href="{% url 'index' %}" class="orange">Accueil</a> |
||||||
|
<a href="{% url 'clubs' %}" class="orange">Clubs</a> |
||||||
|
{% if user.is_authenticated %} |
||||||
|
<a href="{% url 'my-tournaments' %}" class="orange">Mes tournois</a> |
||||||
|
<a href="{% url 'profile' %}">Mon compte</a> |
||||||
|
{% else %} |
||||||
|
<a href="{% url 'login' %}">Se connecter</a> |
||||||
|
{% endif %} |
||||||
|
</nav> |
||||||
|
<h1 class="club my-block topmargin20">Votre panier</h1> |
||||||
|
<div class="grid-x"> |
||||||
|
<div class="small-12 medium-6 large-6 my-block"> |
||||||
|
<div class="bubble"> |
||||||
|
{% if request.user.is_authenticated %} |
||||||
|
<p>Vous êtes déjà connecté en tant que {{ request.user.email }}.</p> |
||||||
|
<a href="{% url 'shop:checkout' %}">Passer à la commande</a> |
||||||
|
{% else %} |
||||||
|
<p>Vous n'êtes pas connecté. Veuillez choisir une option :</p> |
||||||
|
|
||||||
|
<form method="post"> |
||||||
|
{% csrf_token %} |
||||||
|
{{ form.as_p }} |
||||||
|
<button type="submit" name="guest_checkout">Continuer sans créer de compte</button> |
||||||
|
</form> |
||||||
|
|
||||||
|
<hr> |
||||||
|
|
||||||
|
<p>Ou <a href="{% url 'login' %}?next={% url 'shop:checkout' %}">connectez-vous</a> si vous avez déjà un compte.</p> |
||||||
|
|
||||||
|
<hr> |
||||||
|
|
||||||
|
<p>Pas encore de compte ? <a href="{% url 'signup' %}?next={% url 'shop:checkout' %}">Créez-en un maintenant</a></p> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,65 @@ |
|||||||
|
{% extends 'tournaments/base.html' %} |
||||||
|
|
||||||
|
{% block head_title %}Confirmation de commande{% endblock %} |
||||||
|
{% block first_title %}Confirmation de commande{% endblock %} |
||||||
|
{% block second_title %}Merci pour votre commande !{% endblock %} |
||||||
|
|
||||||
|
{% block content %} |
||||||
|
|
||||||
|
<nav class="margin10"> |
||||||
|
<a href="{% url 'shop:product_list' %}">La Boutique</a> |
||||||
|
<a href="{% url 'index' %}" class="orange">Accueil</a> |
||||||
|
<a href="{% url 'clubs' %}" class="orange">Clubs</a> |
||||||
|
{% if user.is_authenticated %} |
||||||
|
<a href="{% url 'my-tournaments' %}" class="orange">Mes tournois</a> |
||||||
|
<a href="{% url 'profile' %}">Mon compte</a> |
||||||
|
{% else %} |
||||||
|
<a href="{% url 'login' %}">Se connecter</a> |
||||||
|
{% endif %} |
||||||
|
</nav> |
||||||
|
<div class="grid-x"> |
||||||
|
<div class="cell medium-6 large-6 my-block"> |
||||||
|
<h1 class="club my-block topmargin20">Détails de la commande</h1> |
||||||
|
<div class="bubble"> |
||||||
|
{% if order_items %} |
||||||
|
<table class="cart-table"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Produit</th> |
||||||
|
<th>Couleur</th> |
||||||
|
<th>Taille</th> |
||||||
|
<th>Quantité</th> |
||||||
|
<th class="price-column">Prix</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% for item in order_items %} |
||||||
|
<tr class="{% cycle 'odd' 'even' %}"> |
||||||
|
<td>{{ item.product.title }}</td> |
||||||
|
<td>{{ item.color.name }}</td> |
||||||
|
<td>{{ item.size.name }}</td> |
||||||
|
<td>{{ item.quantity }}</td> |
||||||
|
<td class="price-column">{{ item.get_total_price }} €</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
</tbody> |
||||||
|
<tfoot> |
||||||
|
<tr> |
||||||
|
<td colspan="3" class="total-label">Total:</td> |
||||||
|
<td class="total-quantity">{{ order_items.total_quantity }}</td> |
||||||
|
<td class="price-column total-price">{{ total }} €</td> |
||||||
|
</tr> |
||||||
|
</tfoot> |
||||||
|
</table> |
||||||
|
|
||||||
|
<div class="order-summary"> |
||||||
|
<p>Votre commande a été passée avec succès !</p> |
||||||
|
<a class="back-to-shop-button" href="{% url 'shop:product_list' %}">Retour à la boutique</a> |
||||||
|
</div> |
||||||
|
{% else %} |
||||||
|
<p>Aucun élément dans la commande.</p> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,21 @@ |
|||||||
|
from django.contrib import messages |
||||||
|
from django.contrib.auth import views as auth_views |
||||||
|
from django.urls import reverse |
||||||
|
from .forms import EmailOrUsernameAuthenticationForm |
||||||
|
|
||||||
|
class CustomLoginView(auth_views.LoginView): |
||||||
|
template_name = 'registration/login.html' |
||||||
|
authentication_form = EmailOrUsernameAuthenticationForm |
||||||
|
print("CustomLoginView") |
||||||
|
|
||||||
|
def get_success_url(self): |
||||||
|
next_url = self.request.POST.get('next') |
||||||
|
print("CustomLoginView", "next_url", next_url, self.request.GET) |
||||||
|
if next_url: |
||||||
|
return next_url |
||||||
|
else: |
||||||
|
return reverse('index') |
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs): |
||||||
|
messages.get_messages(request).used = True |
||||||
|
return super().get(request, *args, **kwargs) |
||||||
Loading…
Reference in new issue