from datetime import date from django.db import models from django.db.models import Q class MonthlyTrip(models.Model): MONTH_CHOICES = [ (1, 'January'), (2, 'February'), (3, 'March'), (4, 'April'), (5, 'May'), (6, 'June'), (7, 'July'), (8, 'August'), (9, 'September'), (10, 'October'), (11, 'November'), (12, 'December'), ] year = models.PositiveIntegerField(verbose_name="Year") month = models.PositiveSmallIntegerField(choices=MONTH_CHOICES, verbose_name="Month") kilometers = models.PositiveIntegerField(default=0, verbose_name="Kilometers") class Meta: constraints = [ models.UniqueConstraint(fields=['year', 'month'], name='unique_monthly_trip') ] verbose_name = "Monthly Trip" verbose_name_plural = "Monthly Trips" def __str__(self): return f"{self.month:02d}.{self.year} : {self.kilometers} km" class FuelPurchase(models.Model): GAS_STATION_CHOICES = [ (0, 'Unknown'), (1, 'Neste'), (2, 'Teboil'), (3, 'ABC'), (4, 'Shell'), (5, 'St1'), (6, 'SEO'), (7, 'Ysi5'), ] OCTANE_CHOICES = [ (95, '95'), (98, '98'), ] CAR_CHOICES = [ (0, 'Unknown'), (1, 'Renault'), (2, 'Nissan'), (3, 'Smart'), ] purchase_date = models.DateField(default=date.today, verbose_name="Purchase Date") total_cost = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Total Cost (€)") price_per_litre = models.DecimalField(max_digits=6, decimal_places=3, verbose_name="Price per Litre (€)") amount_litres = models.DecimalField(max_digits=7, decimal_places=2, verbose_name="Amount (litres)") octane = models.PositiveSmallIntegerField(choices=OCTANE_CHOICES, default=95, verbose_name="Octane") gas_station = models.PositiveSmallIntegerField(choices=GAS_STATION_CHOICES, default=0, verbose_name="Gas Station") car = models.PositiveSmallIntegerField(choices=CAR_CHOICES, default=0, verbose_name="Car") monthly_trip = models.ForeignKey(MonthlyTrip, on_delete=models.CASCADE, related_name='fuel_purchases', verbose_name="Monthly Trip") class Meta: constraints = [ models.UniqueConstraint( fields=[ 'purchase_date', 'total_cost', 'price_per_litre', 'amount_litres', 'octane', 'gas_station', 'car', ], name='unique_fuel_purchase' ), models.CheckConstraint(check=Q(total_cost__gt=0) & Q(total_cost__lt=1000), name="total_cost_range"), models.CheckConstraint(check=Q(price_per_litre__gt=0) & Q(price_per_litre__lt=5), name="price_per_litre_range"), models.CheckConstraint(check=Q(amount_litres__gt=0) & Q(amount_litres__lt=100), name="amount_litres_range"), ] verbose_name = "Fuel Purchase" verbose_name_plural = "Fuel Purchases" def save(self, *args, **kwargs): if not self.amount_litres and self.price_per_litre: self.amount_litres = self.total_cost / self.price_per_litre if not self.monthly_trip_id: month = self.purchase_date.month year = self.purchase_date.year monthly_trip, created = MonthlyTrip.objects.get_or_create( year=year, month=month, defaults={'kilometers': 0} ) self.monthly_trip = monthly_trip super().save(*args, **kwargs) def __str__(self): date_str = self.purchase_date.strftime("%d.%m.%Y") return f"{date_str} : {self.total_cost} € - {self.price_per_litre} €/L"