diff --git a/main/forms.py b/main/forms.py index 39fc414..702480b 100644 --- a/main/forms.py +++ b/main/forms.py @@ -6,7 +6,8 @@ from .models import FuelPurchase class FuelPurchaseForm(forms.ModelForm): class Meta: model = FuelPurchase - fields = ['purchase_date', 'total_cost', 'price_per_litre', 'amount_litres'] + fields = ['purchase_date', 'total_cost', 'price_per_litre', 'amount_litres', 'octane', 'gas_station', 'car',] + widgets = { 'purchase_date': forms.DateInput(attrs={ 'type': 'date', @@ -28,4 +29,8 @@ class FuelPurchaseForm(forms.ModelForm): 'id': 'id_amount_litres', 'readonly': True }), + 'octane': forms.Select(attrs={'class': 'uk-select'}), + 'gas_station': forms.Select(attrs={'class': 'uk-select'}), + 'car': forms.Select(attrs={'class': 'uk-select'}), + } diff --git a/main/migrations/0002_remove_fuelpurchase_unique_fuel_purchase_and_more.py b/main/migrations/0002_remove_fuelpurchase_unique_fuel_purchase_and_more.py new file mode 100644 index 0000000..9968611 --- /dev/null +++ b/main/migrations/0002_remove_fuelpurchase_unique_fuel_purchase_and_more.py @@ -0,0 +1,31 @@ +# Generated by Django 5.2.5 on 2025-08-09 18:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0001_initial'), + ] + + operations = [ + migrations.RemoveConstraint( + model_name='fuelpurchase', + name='unique_fuel_purchase', + ), + migrations.AddField( + model_name='fuelpurchase', + name='gas_station', + field=models.IntegerField(choices=[(0, '-'), (1, 'Neste'), (2, 'Teboil'), (3, 'ABC'), (4, 'Shell'), (5, 'St1'), (6, 'SEO'), (7, 'ysi5')], default=1, verbose_name='Gas Station'), + ), + migrations.AddField( + model_name='fuelpurchase', + name='octane', + field=models.IntegerField(choices=[(95, '95'), (98, '98')], default=95, verbose_name='Octane'), + ), + migrations.AddConstraint( + model_name='fuelpurchase', + constraint=models.UniqueConstraint(fields=('purchase_date', 'total_cost', 'price_per_litre', 'amount_litres', 'octane', 'gas_station'), name='unique_fuel_purchase'), + ), + ] diff --git a/main/migrations/0003_remove_fuelpurchase_unique_fuel_purchase_and_more.py b/main/migrations/0003_remove_fuelpurchase_unique_fuel_purchase_and_more.py new file mode 100644 index 0000000..1050a86 --- /dev/null +++ b/main/migrations/0003_remove_fuelpurchase_unique_fuel_purchase_and_more.py @@ -0,0 +1,26 @@ +# Generated by Django 5.2.5 on 2025-08-09 19:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0002_remove_fuelpurchase_unique_fuel_purchase_and_more'), + ] + + operations = [ + migrations.RemoveConstraint( + model_name='fuelpurchase', + name='unique_fuel_purchase', + ), + migrations.AddField( + model_name='fuelpurchase', + name='car', + field=models.IntegerField(choices=[(0, '_'), (1, 'Renault'), (2, 'Nissan'), (3, 'Smart')], default=3, verbose_name='Car'), + ), + migrations.AddConstraint( + model_name='fuelpurchase', + constraint=models.UniqueConstraint(fields=('purchase_date', 'total_cost', 'price_per_litre', 'amount_litres', 'octane', 'gas_station', 'car'), name='unique_fuel_purchase'), + ), + ] diff --git a/main/models.py b/main/models.py index 661dfd8..dbc072f 100644 --- a/main/models.py +++ b/main/models.py @@ -3,10 +3,37 @@ from django.db.models import F, Q class FuelPurchase(models.Model): + + GAS_STATION_CHOICES = [ + (0, '-'), + (1, 'Neste'), + (2, 'Teboil'), + (3, 'ABC'), + (4, 'Shell'), + (5, 'St1'), + (6, 'SEO'), + (7, 'ysi5'), + ] + + OCTANE_CHOICES = [ + (95, '95'), + (98, '98'), + ] + + CAR_CHOICES = [ + (0, '_'), + (1, 'Renault'), + (2, 'Nissan'), + (3, 'Smart'), + ] + purchase_date = models.DateField(null=False, blank=False, verbose_name="Purchase Date") total_cost = models.DecimalField(null=False, blank=False, max_digits=10, decimal_places=2, verbose_name="Total Cost (€)") price_per_litre = models.DecimalField(null=False, blank=False, max_digits=6, decimal_places=3, verbose_name="Price per Litre (€)") amount_litres = models.DecimalField(null=False, blank=False, max_digits=7, decimal_places=2, verbose_name="Amount (litres)") + octane = models.IntegerField(choices=OCTANE_CHOICES, default=95, verbose_name="Octane") + gas_station = models.IntegerField(choices=GAS_STATION_CHOICES, default=1, verbose_name="Gas Station") + car = models.IntegerField(choices=CAR_CHOICES, default=3, verbose_name="Car") class Meta: constraints = [ @@ -16,6 +43,9 @@ class FuelPurchase(models.Model): 'total_cost', 'price_per_litre', 'amount_litres', + 'octane', + 'gas_station', + 'car', ], name='unique_fuel_purchase' ), diff --git a/main/templates/main/fuelpurchase_list.html b/main/templates/main/fuelpurchase_list.html index 239c9b0..c1603e5 100644 --- a/main/templates/main/fuelpurchase_list.html +++ b/main/templates/main/fuelpurchase_list.html @@ -14,12 +14,12 @@
← Previous -
- {% for month_date in available_months %} {% endfor %} @@ -32,7 +32,7 @@

Summary

    -
  • Total Cost: {{ summary.total_cost_sum|default:"0.00" }} €
  • +
  • Total Cost: {{ summary.total_cost_sum|floatformat:2|default:"0.00" }} €
  • Total Litres: {{ summary.total_litres_sum|floatformat:2|default:"0.00" }} L
  • Average Litre Price: {{ summary.avg_price|floatformat:3|default:"0.000" }} €
  • Min Litre Price: {{ summary.min_price|floatformat:3|default:"0.000" }} €
  • @@ -49,6 +49,9 @@ Total Cost (€) Litre Price (€) Amount (litres) + Octane + Gas Station + Car @@ -58,6 +61,9 @@ {{ purchase.total_cost }} {{ purchase.price_per_litre }} {{ purchase.amount_litres }} + {{ purchase.octane }} + {{ purchase.get_gas_station_display }} + {{ purchase.get_car_display }} {% endfor %} diff --git a/main/templates/registration/login.html b/main/templates/registration/login.html new file mode 100644 index 0000000..497dae5 --- /dev/null +++ b/main/templates/registration/login.html @@ -0,0 +1,38 @@ +{% extends "base.html" %} + +{% block content %} +
    + + {% csrf_token %} +
    + + Kirjaudu sisään + + {% if form.errors %} +
    +

    Virheellinen käyttäjätunnus tai salasana.

    +
    + {% endif %} + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    + +
    +{% endblock %} diff --git a/main/urls.py b/main/urls.py index 4be77b0..7ce37fc 100644 --- a/main/urls.py +++ b/main/urls.py @@ -1,3 +1,4 @@ +from django.contrib.auth import views as auth_views from django.urls import path from . import views @@ -6,4 +7,6 @@ urlpatterns = [ path("", views.FuelPurchaseMonthlyListView.as_view(), name="fuelpurchase_list_current"), path("//", views.FuelPurchaseMonthlyListView.as_view(), name="fuelpurchase_list"), path("add/", views.FuelPurchaseCreateView.as_view(), name="fuelpurchase_add"), + path('accounts/login/', auth_views.LoginView.as_view(template_name='registration/login.html'), name='login'), + path('accounts/logout/', auth_views.LogoutView.as_view(next_page='/'), name='logout'), ] diff --git a/main/views.py b/main/views.py index 2a00f61..7b36187 100644 --- a/main/views.py +++ b/main/views.py @@ -1,6 +1,8 @@ from calendar import monthrange from datetime import date, timedelta +from django.contrib.auth.decorators import login_required +from django.contrib.auth.mixins import LoginRequiredMixin from django.db.models import Avg, Max, Min, Sum from django.http import HttpResponse from django.shortcuts import render @@ -63,7 +65,7 @@ class FuelPurchaseMonthlyListView(ListView): return context -class FuelPurchaseCreateView(CreateView): +class FuelPurchaseCreateView(LoginRequiredMixin, CreateView): model = FuelPurchase form_class = FuelPurchaseForm template_name = "main/fuelpurchase_add.html"