Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions padam_django/apps/geography/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,18 @@
@admin.register(models.Place)
class PlaceAdmin(admin.ModelAdmin):
pass

@admin.register(models.BusStop)
class BusStopAdmin(admin.ModelAdmin):
pass


class BusShiftStopInline(admin.TabularInline):
model = models.BusShiftStop
fields = ['bus_stop', 'order', 'scheduled_time']


@admin.register(models.BusShift)
class BusShiftAdmin(admin.ModelAdmin):
list_display = ['id', 'bus', 'driver', 'departure_time', 'arrival_time', 'duration']
inlines = [BusShiftStopInline]
22 changes: 22 additions & 0 deletions padam_django/apps/geography/migrations/0002_busstop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 4.2.16 on 2026-01-08 18:33

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('geography', '0001_initial'),
]

operations = [
migrations.CreateModel(
name='BusStop',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, verbose_name='Name of the bus stop')),
('place', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='geography.place')),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Generated by Django 4.2.16 on 2026-01-08 19:06

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('fleet', '0002_auto_20211109_1456'),
('geography', '0002_busstop'),
]

operations = [
migrations.CreateModel(
name='BusShift',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('bus', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shifts', to='fleet.bus')),
('driver', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shifts', to='fleet.driver')),
],
),
migrations.CreateModel(
name='BusShiftStop',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('order', models.PositiveIntegerField(verbose_name='Stop order in the shift')),
('scheduled_time', models.DateTimeField(verbose_name='Scheduled time at this stop')),
('bus_shift', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='geography.busshift')),
('bus_stop', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='geography.busstop')),
],
options={
'ordering': ['order'],
'unique_together': {('bus_shift', 'order'), ('bus_shift', 'bus_stop')},
},
),
migrations.AddField(
model_name='busshift',
name='stops',
field=models.ManyToManyField(related_name='shifts', through='geography.BusShiftStop', to='geography.busstop'),
),
]
52 changes: 52 additions & 0 deletions padam_django/apps/geography/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,55 @@ class Meta:

def __str__(self):
return f"Place: {self.name} (id: {self.pk})"


class BusStop(models.Model):
name = models.CharField("Name of the bus stop", max_length=50)
place = models.ForeignKey(Place, on_delete=models.CASCADE)

def __str__(self):
return f"Bus stop: {self.name} (id: {self.pk})"


class BusShift(models.Model):
"""Represents a bus shift (trajet de bus)"""
bus = models.ForeignKey('fleet.Bus', on_delete=models.CASCADE, related_name='shifts')
driver = models.ForeignKey('fleet.Driver', on_delete=models.CASCADE, related_name='shifts')
stops = models.ManyToManyField(BusStop, through='BusShiftStop', related_name='shifts')

def __str__(self):
return f"Shift {self.pk}: Bus {self.bus.licence_plate} - Driver {self.driver.user.username}"

@property
def departure_time(self):
"""Returns the time of the first stop"""
first_stop = self.busshiftstop_set.first()
return first_stop.scheduled_time if first_stop else None

@property
def arrival_time(self):
"""Returns the time of the last stop"""
last_stop = self.busshiftstop_set.last()
return last_stop.scheduled_time if last_stop else None

@property
def duration(self):
"""Returns the total duration of the shift"""
if self.departure_time and self.arrival_time:
return self.arrival_time - self.departure_time
return None


class BusShiftStop(models.Model):
"""Represents a stop during a bus shift with order and time"""
bus_shift = models.ForeignKey(BusShift, on_delete=models.CASCADE)
bus_stop = models.ForeignKey(BusStop, on_delete=models.CASCADE)
order = models.PositiveIntegerField("Stop order in the shift")
scheduled_time = models.DateTimeField("Scheduled time at this stop")

class Meta:
ordering = ['order']
unique_together = (('bus_shift', 'order'), ('bus_shift', 'bus_stop'))

def __str__(self):
return f"Shift {self.bus_shift.pk} - Stop {self.order}: {self.bus_stop.name} at {self.scheduled_time}"