+ {% blocktranslate trimmed %} + You are authenticated as {{ username }}, but are not authorized to + access this page. Would you like to login to a different account? + {% endblocktranslate %} +
+ {% endif %} + + +diff --git a/Finanzas/finanzas/accounts/.gitignore b/Finanzas/finanzas/accounts/.gitignore new file mode 100644 index 0000000..62616c7 --- /dev/null +++ b/Finanzas/finanzas/accounts/.gitignore @@ -0,0 +1 @@ +migrations/ diff --git a/Finanzas/finanzas/accounts/__init__.py b/Finanzas/finanzas/accounts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Finanzas/finanzas/accounts/admin.py b/Finanzas/finanzas/accounts/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/Finanzas/finanzas/accounts/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/Finanzas/finanzas/accounts/apps.py b/Finanzas/finanzas/accounts/apps.py new file mode 100644 index 0000000..3e3c765 --- /dev/null +++ b/Finanzas/finanzas/accounts/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AccountsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'accounts' diff --git a/Finanzas/finanzas/accounts/models.py b/Finanzas/finanzas/accounts/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/Finanzas/finanzas/accounts/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/Finanzas/finanzas/accounts/tests.py b/Finanzas/finanzas/accounts/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/Finanzas/finanzas/accounts/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/Finanzas/finanzas/accounts/urls.py b/Finanzas/finanzas/accounts/urls.py new file mode 100644 index 0000000..532af83 --- /dev/null +++ b/Finanzas/finanzas/accounts/urls.py @@ -0,0 +1,8 @@ +# accounts/urls.py +from django.urls import path +from django.contrib.auth import views as auth_views + +urlpatterns = [ + path('login/', auth_views.LoginView.as_view(), name='login'), + path('logout/', auth_views.LogoutView.as_view(), name='logout'), +] diff --git a/Finanzas/finanzas/accounts/views.py b/Finanzas/finanzas/accounts/views.py new file mode 100644 index 0000000..2536b37 --- /dev/null +++ b/Finanzas/finanzas/accounts/views.py @@ -0,0 +1 @@ +from django.shortcuts import render diff --git a/Finanzas/finanzas/apuntes/__init__.py b/Finanzas/finanzas/apuntes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Finanzas/finanzas/apuntes/admin.py b/Finanzas/finanzas/apuntes/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/Finanzas/finanzas/apuntes/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/Finanzas/finanzas/apuntes/apps.py b/Finanzas/finanzas/apuntes/apps.py new file mode 100644 index 0000000..a6b5f1b --- /dev/null +++ b/Finanzas/finanzas/apuntes/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ApuntesConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'apuntes' diff --git a/Finanzas/finanzas/apuntes/forms.py b/Finanzas/finanzas/apuntes/forms.py new file mode 100644 index 0000000..44918a6 --- /dev/null +++ b/Finanzas/finanzas/apuntes/forms.py @@ -0,0 +1,52 @@ +from django import forms +from django.contrib.auth.forms import UserCreationForm, UserChangeForm + +from .models import Cuentas, Apuntes, ReyMotaUser, Tipos + + +class CuentasForm(forms.ModelForm): + class Meta: + model = Cuentas + fields = ['nombre', 'saldo_inicial', 'tipo'] + + nombre = forms.CharField( + widget=forms.TextInput(attrs={'class': 'form-control'})) + saldo_inicial = forms.DecimalField( + widget=forms.TextInput(attrs={'class': 'form-control'})) + tipo = forms.ModelChoiceField( + queryset=Tipos.objects.all(), + widget=forms.TextInput(attrs={'class': 'form-control'})) + + +class ApuntesForm(forms.ModelForm): + class Meta: + model = Apuntes + fields = ['fecha', 'cta_origen', 'cta_destino', 'importe'] + + fecha = forms.DateField( + widget=forms.DateInput(attrs={'type': 'date', 'class': 'form-control'})) + + cta_origen = forms.ModelChoiceField( + queryset=Cuentas.objects.all(), + widget=forms.Select(attrs={'class': 'form-control'})) + + cta_destino = forms.ModelChoiceField( + queryset=Cuentas.objects.all(), + widget=forms.Select(attrs={'class': 'form-control'})) + + importe = forms.DecimalField( + widget=forms.NumberInput(attrs={'class': 'form-control'})) + +class ReyMotaUserCreationForm(UserCreationForm): + + class Meta: + model = ReyMotaUser + fields = ("email", "nombre", "foto") + labels = {'email': 'Dirección de correo'} + + +class ReyMotaUserChangeForm(UserChangeForm): + + class Meta: + model = ReyMotaUser + fields = ("email", "foto") diff --git a/Finanzas/finanzas/apuntes/managers.py b/Finanzas/finanzas/apuntes/managers.py new file mode 100644 index 0000000..0b8128d --- /dev/null +++ b/Finanzas/finanzas/apuntes/managers.py @@ -0,0 +1,34 @@ +from django.contrib.auth.base_user import BaseUserManager +from django.utils.translation import gettext_lazy as _ + + +class ReyMotaUserManager(BaseUserManager): + """ + ReyMota user model manager where email is the unique identifiers + for authentication instead of usernames. + """ + def create_user(self, email, password, **extra_fields): + """ + Create and save a user with the given email and password. + """ + if not email: + raise ValueError(_("The Email must be set")) + email = self.normalize_email(email) + user = self.model(email=email, **extra_fields) + user.set_password(password) + user.save() + return user + + def create_superuser(self, email, password, **extra_fields): + """ + Create and save a SuperUser with the given email and password. + """ + extra_fields.setdefault("is_staff", True) + extra_fields.setdefault("is_superuser", True) + extra_fields.setdefault("is_active", True) + + if extra_fields.get("is_staff") is not True: + raise ValueError(_("Superuser must have is_staff=True.")) + if extra_fields.get("is_superuser") is not True: + raise ValueError(_("Superuser must have is_superuser=True.")) + return self.create_user(email, password, **extra_fields) diff --git a/Finanzas/finanzas/apuntes/migrations/0001_initial.py b/Finanzas/finanzas/apuntes/migrations/0001_initial.py new file mode 100644 index 0000000..ec3fccd --- /dev/null +++ b/Finanzas/finanzas/apuntes/migrations/0001_initial.py @@ -0,0 +1,66 @@ +# Generated by Django 5.1 on 2024-09-02 14:10 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='Cuentas', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nombre', models.TextField(max_length=20)), + ('saldo_inicial', models.DecimalField(decimal_places=2, max_digits=10)), + ('saldo_actual', models.DecimalField(decimal_places=2, max_digits=10)), + ], + ), + migrations.CreateModel( + name='Tipos', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tipo', models.TextField(max_length=10)), + ], + ), + migrations.CreateModel( + name='ReyMotaUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')), + ('foto', models.ImageField(blank=True, default='profile_images/default.jpg', upload_to='profile_images')), + ('is_staff', models.BooleanField(default=False)), + ('is_active', models.BooleanField(default=True)), + ('nombre', models.CharField(blank=True, max_length=200, null=True)), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Apuntes', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('fecha', models.DateField()), + ('importe', models.DecimalField(decimal_places=2, max_digits=10)), + ('cta_destino', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='destino', to='apuntes.cuentas')), + ('cta_origen', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='origen', to='apuntes.cuentas')), + ], + ), + migrations.AddField( + model_name='cuentas', + name='tipo', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='apuntes.tipos'), + ), + ] diff --git a/Finanzas/finanzas/apuntes/migrations/__init__.py b/Finanzas/finanzas/apuntes/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Finanzas/finanzas/apuntes/models.py b/Finanzas/finanzas/apuntes/models.py new file mode 100644 index 0000000..9380de2 --- /dev/null +++ b/Finanzas/finanzas/apuntes/models.py @@ -0,0 +1,37 @@ +from django.db import models +from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin +from django.utils.translation import gettext_lazy as _ + +from .managers import ReyMotaUserManager + +# Create your models here. + +class ReyMotaUser(AbstractBaseUser, PermissionsMixin): + email = models.EmailField(_("email address"), unique=True) + foto = models.ImageField(upload_to="profile_images", default="profile_images/default.jpg", blank=True) + is_staff = models.BooleanField(default=False) + is_active = models.BooleanField(default=True) + nombre = models.CharField(max_length=200, blank=True, null=True) + + USERNAME_FIELD = "email" + REQUIRED_FIELDS = [] + + objects = ReyMotaUserManager() + + def __str__(self): + return self.email + +class Tipos(models.Model): + tipo = models.TextField(max_length=10) + +class Cuentas(models.Model): + nombre = models.TextField(max_length=20) + saldo_inicial = models.DecimalField(max_digits=10, decimal_places=2) + saldo_actual = models.DecimalField(max_digits=10, decimal_places=2) + tipo = models.ForeignKey(Tipos, on_delete=models.CASCADE) + +class Apuntes(models.Model): + fecha = models.DateField() + cta_origen = models.ForeignKey(Cuentas, on_delete=models.CASCADE, related_name='origen') + cta_destino = models.ForeignKey(Cuentas, on_delete=models.CASCADE, related_name='destino') + importe = models.DecimalField(max_digits=10, decimal_places=2) diff --git a/Finanzas/finanzas/apuntes/templates/404.html b/Finanzas/finanzas/apuntes/templates/404.html new file mode 100644 index 0000000..6fc7ab0 --- /dev/null +++ b/Finanzas/finanzas/apuntes/templates/404.html @@ -0,0 +1,14 @@ +{% extends 'base.html' %} + +{% block content %} + +
No hay imágen disponible
+ {% endif %} +| Fecha | +Kilómetros | +Litros | +Importe | +Descuento | +Precio por litro | +Kms recorridos | +Consumo/100 kms | +
|---|---|---|---|---|---|---|---|
| {{ apunte.fecha }} | +{{ apunte.kms }} | +{{ apunte.litros }} | +{{ apunte.importe }} | +{{ apunte.descuento }} | +{{ apunte.precioxlitro }} | +{{ apunte.kmsrecorridos }} | +{{ apunte.consumo }} | +
No se han encontrado apuntes para este cuenta
+ {% endif %} +| Fecha | +Cuenta | +Kilómetros | +Litros | +Importe | +Descuento | +Precio por litro | +Kms recorridos | +Consumo/100 kms | +
|---|---|---|---|---|---|---|---|---|
| {{ apunte.fecha }} | +{{ apunte.cuenta.matricula }} | +{{ apunte.kms }} | +{{ apunte.litros }} | +{{ apunte.importe }} € | +{{ apunte.descuento }} € | +{{ apunte.precioxlitro }} € | +{{ apunte.kmsrecorridos }} | +{{ apunte.consumo }} | +
+ {% blocktranslate count counter=form.errors.items|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktranslate %} +
+ {% endif %} + + {% if form.non_field_errors %} + {% for error in form.non_field_errors %} ++ {{ error }} +
+ {% endfor %} + {% endif %} + ++ {% blocktranslate trimmed %} + You are authenticated as {{ username }}, but are not authorized to + access this page. Would you like to login to a different account? + {% endblocktranslate %} +
+ {% endif %} + + +