Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b928550
feat: database
YRM2963 Nov 4, 2025
800e009
db.sqlite3
YRM2963 Nov 4, 2025
0211f55
Correción de fallos de .gitignore
YRM2963 Nov 5, 2025
62745b6
Nuevo .gitignore
YRM2963 Nov 5, 2025
71bafd4
feat: Creación base de datos
YRM2963 Nov 5, 2025
c3674cd
Correccion bd y .gitignore
YRM2963 Nov 5, 2025
dec60b5
Merge pull request #11 from WBR4892/feature/database
WBR4892 Nov 5, 2025
a3edc7c
Creación de la vista de la información legal de Essenza
Nov 6, 2025
90995e4
Funcionalidad de registro añadida
WVH7591 Nov 6, 2025
7066c01
Corrección del Usuario en la base de datos
Nov 7, 2025
11a0f73
Merge pull request #13 from WBR4892/feature/database
YRM2963 Nov 7, 2025
1f90a99
Merge pull request #12 from WBR4892/feature/infoLegalEssenza
YRM2963 Nov 7, 2025
d8191ca
commit
Nov 7, 2025
e1dd816
Funcionalidad login implementada
Nov 7, 2025
1504a67
Correcciones pequeñas y base de datos actualizada
Nov 7, 2025
e5e7dd4
Merge pull request #14 from WBR4892/feature/login
WBR4892 Nov 7, 2025
70af7f2
Incorporación de la funcionalidad del Logout
KBC8043 Nov 7, 2025
c4bdf32
Merge pull request #15 from WBR4892/feature/logout
WBR4892 Nov 7, 2025
2d29978
Tests de la funcionalidad login
Nov 8, 2025
3fd2840
Arreglos test funcionalidad login
Nov 8, 2025
b807ff4
Corrección de redirección de logout
Nov 8, 2025
9f3d8ea
Merge pull request #16 from WBR4892/feature/login
WBR4892 Nov 8, 2025
236176d
Merge branch 'develop' of https://github.eii.us.es/WBR4892/PGPI-G1.11…
Nov 8, 2025
a9c176d
Base de datos actualizada
Nov 8, 2025
3a0467e
Muevo la base de datos a su sitio correcto
Nov 8, 2025
69f1094
Correccion de vista del escaparate como invitado
Nov 8, 2025
1a0fa3b
Tests de registro creados correctamente
Nov 9, 2025
9be0a95
Merge pull request #17 from WBR4892/feature/register
XGC1564 Nov 9, 2025
f4d9a1d
añadir y corregir pruebas de LogoutView
KBC8043 Nov 9, 2025
e95d177
Merge pull request #18 from WBR4892/feature/logout
WBR4892 Nov 9, 2025
9164706
Documentación Sprint 1
Nov 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions essenza/.gitignore → .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ __pycache__/
# Entorno virtual
venv/
.env/
.venv

# Archivos de base de datos
db.sqlite3

# Archivos de migraciones (si quieres omitirlos)
*/migrations/__pycache__/
*/migrations/*.py
**/migrations/__pycache__/
**/migrations/*.py

# Archivos de configuración de VSCode
.vscode/

# Archivos de Django estáticos
staticfiles/

**/*.sqlite3
Binary file not shown.
Binary file added docs/Iteración 1/PRODUCT BACKLOG.pdf
Binary file not shown.
Binary file not shown.
Binary file added docs/Iteración 1/REGISTRO DE CAMBIOS_v1.0.pdf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added docs/Iteración 1/SPRINT RETROSPECTIVE.pdf
Binary file not shown.
Binary file added docs/Iteración 1/SPRINT REVIEW.pdf
Binary file not shown.
Binary file added docs/Iteración 1/Sprint Backlog 1.pdf
Binary file not shown.
Binary file added essenza/db.sqlite3
Binary file not shown.
19 changes: 16 additions & 3 deletions essenza/essenza/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,16 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user',
'product',
'order',
'info',
]

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
Expand All @@ -54,11 +59,12 @@
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [ BASE_DIR / 'templates' ],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.request',
'django.template.context_processors.i18n',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
Expand Down Expand Up @@ -102,7 +108,7 @@
# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/

LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'es'

TIME_ZONE = 'UTC'

Expand All @@ -115,8 +121,15 @@
# https://docs.djangoproject.com/en/5.2/howto/static-files/

STATIC_URL = 'static/'

STATICFILES_DIRS = [BASE_DIR / 'static']
# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# -----------------------------------------------------------------
# SOLUCIÓN AL ERROR E304
# Especifica que nuestro modelo 'Usuario' en la app 'user'
# es el modelo de autenticación oficial.
# -----------------------------------------------------------------
AUTH_USER_MODEL = 'user.Usuario'
70 changes: 67 additions & 3 deletions essenza/essenza/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from django.contrib import admin
from django.urls import path
from django.urls import path, include
from django.http import HttpResponse
from info.views import info_view
from product.views import EscaparateView
import user

def home(request):
html = """
Expand All @@ -14,6 +17,7 @@ def home(request):
text-align: center;
padding-top: 100px;
color: #444;
position: relative;
}
h1 {
color: #c06b3e;
Expand All @@ -24,19 +28,79 @@ def home(request):
font-size: 20px;
color: #555;
}
.info-button {
position: absolute;
top: 20px;
left: 20px;
width: 30px;
height: 30px;
background-color: #c06b3e;
border-radius: 50%;
text-align: center;
line-height: 30px;
font-size: 18px;
font-weight: bold;
color: white;
text-decoration: none;
cursor: pointer;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
transition: background-color 0.3s;
}
.info-button:hover { background-color: #a35a34; }
.button-container {
margin-top: 30px; /* Espacio desde el texto de arriba */
display: flex;
flex-direction: column; /* Apila los botones verticalmente */
align-items: center; /* Centra los botones horizontalmente */
gap: 20px; /* Espacio automático entre cada botón */
}
.action-button {
padding: 15px 35px;
background-color: #c06b3e;
color: white;
font-size: 15px;
font-weight: bold;
border: none;
border-radius: 10px;
cursor: pointer;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
text-decoration: none;
transition: background-color 0.3s, transform 0.2s;
display: block;
width: 300px; /* Ancho fijo para que se vean uniformes */
box-sizing: border-box; /* Para que el padding no afecte el ancho */
}
.action-button:hover {
background-color: #a35a34;
transform: scale(1.05); /* Efecto de zoom simple */
}
</style>
</head>
<body>
<a href="/info/" class="info-button" title="Información Legal y Contacto">i</a>
<h1>Bienvenidos a Essenza</h1>
<p>Tu espacio online de cosmética natural, belleza y cuidado personal.</p>
<p>Explora nuestros productos, descubre nuevas fragancias y disfruta de la experiencia Essenza 🌸</p>
<div class="button-container">
<a href="/user/register" class="action-button" title="Registro">Registro</a>
<a href="/user/login" class="action-button" title="Iniciar Sesión">Iniciar sesión</a>
<a href="/escaparate" class="action-button" title="invitado">Continuar como invitado</a>
</div>
</body>
</html>
"""
return HttpResponse(html)

urlpatterns = [
path('', home, name='home'),
path('info/', info_view, name='info-home'),
path("user/", include("user.urls")),
path('admin/', admin.site.urls),
]

path('escaparate/', EscaparateView.as_view(), name='escaparate')
]
Empty file added essenza/info/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions essenza/info/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
6 changes: 6 additions & 0 deletions essenza/info/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class InfoConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'info'
3 changes: 3 additions & 0 deletions essenza/info/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.db import models

# Create your models here.
3 changes: 3 additions & 0 deletions essenza/info/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
101 changes: 101 additions & 0 deletions essenza/info/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# views.py (donde se encuentra la función info_view)

from django.http import HttpResponse
# from django.shortcuts import render # No se usa ya que el HTML está en HttpResponse

def info_view(request):
# CIF inventado para la S.L. Essenza: B87654321

html = """
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Condiciones Legales e Información de Essenza</title>
<style>
body {
font-family: 'Segoe UI', Arial, sans-serif;
background-color: #fcf6f5; /* Tono suave de Essenza */
color: #444;
padding: 40px;
line-height: 1.6;
max-width: 900px;
margin: 0 auto;
}
h2 {
color: #b15b74; /* Color principal de Essenza */
border-bottom: 2px solid #e0c8c0;
padding-bottom: 5px;
margin-top: 30px;
}
h3 {
color: #c06b3e; /* Tono complementario */
margin-top: 20px;
}
p, ul {
font-size: 16px;
margin-bottom: 15px;
text-align: justify;
}
a {
color: #c06b3e;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
header {
text-align: center;
margin-bottom: 40px;
}
.center-text {
text-align: center;
}
</style>
</head>
<body>
<header>
<h1 style="color: #b15b74; font-size: 32px;">Información Legal y Condiciones de Venta de Essenza</h1>
<p class="center-text"><a href="/">Volver a la Página Principal</a></p>
</header>
<h2>1. Identificación y Aviso Legal</h2>
<p>Essenza S.L. es la denominación social y el nombre comercial de la tienda online dedicada a la venta de productos de cosmética y cuidado personal, rigiéndose su actividad por la legislación española vigente. En cumplimiento del deber de información recogido en la Ley 34/2002 de Servicios de la Sociedad de la Información y Comercio Electrónico (LSSI-CE) y en el Real Decreto 85/2018 sobre productos cosméticos, a continuación se detallan los datos de identificación del titular de este sitio web:</p>
<ul>
<li>Denominación Social: Essenza S.L.</li>
<li>C.I.F.: B87654321</li>
<li>Domicilio Social: C/Mateos Gago, Sevilla (España)</li>
<li>Correo Electrónico de Contacto: <a href="mailto:info@essenza.com">info@essenza.com</a></li>
<li>Objeto Social: Comercio minorista de productos cosméticos y de perfumería, enfocado en cosmética natural de alta calidad.</li>
</ul>
<h2>2. Condiciones Generales de Venta (CGV)</h2>
<p>Estas condiciones regulan la relación contractual de compraventa entre Essenza y usted desde el momento en que realiza un pedido en nuestra web. La formalización de un pedido implica la lectura, comprensión y aceptación expresa de estas Condiciones Generales de Venta en su totalidad, siendo de obligado cumplimiento para ambas partes.</p>
<h3>2.1. Información, Trazabilidad y Calidad del Producto</h3>
<p>Essenza garantiza que todos sus productos han pasado rigurosos controles de calidad y cumplen con los requisitos de seguridad establecidos por la normativa europea (Reglamento CE 1223/2009). La información detallada de ingredientes, modo de uso, precauciones y el Periodo Después de la Apertura (PAO) se encuentra de forma clara y accesible en la ficha de cada producto y en su etiquetado. Mantenemos un estricto control de trazabilidad para garantizar la seguridad de todos los artículos de cosmética que comercializamos.</p>
<h3>2.2. Proceso de Compra y Precio</h3>
<p>El proceso de compra se considera finalizado y vinculante una vez que el pago ha sido confirmado. Todos los precios mostrados en el sitio web están expresados en euros (€) e incluyen el Impuesto sobre el Valor Añadido (I.V.A.) legalmente aplicable. Los gastos de envío serán calculados en base al peso y la dirección de entrega, siendo detallados y aceptados por el Cliente antes de la confirmación final de la compra.</p>
<h3>2.3. Envíos, Plazos y Riesgos</h3>
<ul>
<li><strong>Plazo:</strong> Los plazos de entrega estimados son de 3-5 días laborables y se contabilizan desde la confirmación del pago.</li>
<li><strong>Riesgo:</strong> El riesgo de pérdida o daño de los productos se transmite al Cliente en el momento en que usted o un tercero indicado por usted adquiera la posesión material de los bienes.</li>
</ul>
<h3>2.4. Política de Desistimiento y Devoluciones</h3>
<p>De acuerdo con la Ley General para la Defensa de los Consumidores y Usuarios, el Cliente dispone de 14 días naturales desde la recepción del pedido para ejercer su derecho de desistimiento. Condición Específica para Cosmética: Por estrictas razones de higiene, seguridad y protección de la salud, no se admitirá la devolución de productos cosméticos que hayan sido abiertos, desprecintados o usados. En caso de desistimiento válido, los costes directos de la devolución (envío de vuelta) correrán a cargo del cliente, salvo si la causa es un producto defectuoso o un error de Essenza.</p>
<h2>3. Política de Privacidad (RGPD)</h2>
<p>En Essenza, su privacidad es nuestra prioridad. Los datos personales recabados (nombre, dirección, email, datos de pago) a través de la web son tratados bajo la legitimación de la ejecución de un contrato (para gestionar su pedido) o el consentimiento (para el newsletter). Nos comprometemos a no ceder sus datos a terceros, salvo obligación legal. Usted puede ejercer en todo momento sus derechos de Acceso, Rectificación, Supresión, Limitación, Portabilidad y Oposición (ARSLOP) enviando una solicitud a <a href="mailto:info@essenza.com">info@essenza.com</a>.</p>
<footer style="margin-top: 50px; border-top: 1px solid #ddd; padding-top: 20px; text-align: center;">
<p class="center-text">&copy; 2025 Essenza S.L. Todos los derechos reservados. El uso de este sitio implica la aceptación de sus Condiciones Legales.</p>
</footer>
</body>
</html>
"""
return HttpResponse(html)
Empty file added essenza/order/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions essenza/order/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.contrib import admin
from .models import Order, OrderProduct, Status
# Register your models here.

admin.site.register(Order)
admin.site.register(OrderProduct)
6 changes: 6 additions & 0 deletions essenza/order/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class OrderConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'order'
27 changes: 27 additions & 0 deletions essenza/order/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from django.db import models

# Create your models here.
class Status(models.TextChoices):
PENDING = 'pending', 'Pending'
PAID = 'paid', 'Paid'
SHIPPED = 'shipped', 'Shipped'

class Order(models.Model):
user = models.ForeignKey('user.Usuario', on_delete=models.CASCADE, related_name='orders')
adress = models.CharField(max_length=255)
placed_at = models.DateTimeField(auto_now=True)
total_price = models.DecimalField(max_digits=10, decimal_places=2)
status = models.CharField(max_length=10, choices=Status.choices, default=Status.PENDING)

def __str__(self):
return f"Order {self.id} by {self.user.email}"


class OrderProduct(models.Model):
order = models.ForeignKey('order.Order', on_delete=models.CASCADE, related_name='order_products')
product = models.ForeignKey('product.Product', on_delete=models.CASCADE, related_name='product_orders')
quantity = models.IntegerField()
unity_price = models.DecimalField(max_digits=10, decimal_places=2)

def __str__(self):
return f"{self.quantity} of {self.product.name} in order {self.order.id}"
3 changes: 3 additions & 0 deletions essenza/order/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
3 changes: 3 additions & 0 deletions essenza/order/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.shortcuts import render

# Create your views here.
Empty file added essenza/product/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions essenza/product/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.contrib import admin
from .models import Category, Product

# Register your models here.
admin.site.register(Product)
6 changes: 6 additions & 0 deletions essenza/product/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class ProductConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'product'
22 changes: 22 additions & 0 deletions essenza/product/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from django.db import models

# Create your models here.
class Category(models.TextChoices):
MAQUILLAJE = 'maquillaje', 'Maquillaje'
TRATAMIENTO = 'tratamiento', 'Tratamiento'
CABELLO = 'cabello', 'Cabello'
PERFUME = 'perfume', 'Perfume'

class Product(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
categoria = models.CharField(max_length=20, choices=Category.choices)
brand = models.CharField(max_length=255)
price = models.DecimalField(max_digits=10, decimal_places=2)
foto = models.ImageField(upload_to='profile_pics/', null=True, blank=True)
stock = models.IntegerField()
is_active = models.BooleanField(default=False)

def __str__(self):
return self.name

3 changes: 3 additions & 0 deletions essenza/product/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
Loading