From 3956b5337849ca2564130c00cd9b1eee041fb545 Mon Sep 17 00:00:00 2001 From: Damien Date: Wed, 12 Jun 2024 12:27:47 +0200 Subject: [PATCH 1/3] Add BusShift layer --- padam_django/apps/BusShift/__init__.py | 0 padam_django/apps/BusShift/admin.py | 8 ++++++++ padam_django/apps/BusShift/apps.py | 5 +++++ padam_django/apps/BusShift/factories.py | 14 ++++++++++++++ padam_django/apps/BusShift/management/__init__.py | 0 .../apps/BusShift/management/commands/__init__.py | 0 .../management/commands/create_busshift.py | 13 +++++++++++++ padam_django/apps/BusShift/migrations/__init__.py | 0 padam_django/apps/BusShift/models.py | 12 ++++++++++++ padam_django/settings.py | 1 + 10 files changed, 53 insertions(+) create mode 100644 padam_django/apps/BusShift/__init__.py create mode 100644 padam_django/apps/BusShift/admin.py create mode 100644 padam_django/apps/BusShift/apps.py create mode 100644 padam_django/apps/BusShift/factories.py create mode 100644 padam_django/apps/BusShift/management/__init__.py create mode 100644 padam_django/apps/BusShift/management/commands/__init__.py create mode 100644 padam_django/apps/BusShift/management/commands/create_busshift.py create mode 100644 padam_django/apps/BusShift/migrations/__init__.py create mode 100644 padam_django/apps/BusShift/models.py diff --git a/padam_django/apps/BusShift/__init__.py b/padam_django/apps/BusShift/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/padam_django/apps/BusShift/admin.py b/padam_django/apps/BusShift/admin.py new file mode 100644 index 00000000..f2b82245 --- /dev/null +++ b/padam_django/apps/BusShift/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin + +from . import models + + +@admin.register(models.BusShift) +class BusShiftAdmin(admin.ModelAdmin): + pass diff --git a/padam_django/apps/BusShift/apps.py b/padam_django/apps/BusShift/apps.py new file mode 100644 index 00000000..51f8fff5 --- /dev/null +++ b/padam_django/apps/BusShift/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class BusShiftConfid(AppConfig): + name = "padam_django.apps.BusShift" diff --git a/padam_django/apps/BusShift/factories.py b/padam_django/apps/BusShift/factories.py new file mode 100644 index 00000000..c8d78a0a --- /dev/null +++ b/padam_django/apps/BusShift/factories.py @@ -0,0 +1,14 @@ +import factory +from faker import Faker + +from . import models + + +fake = Faker(['fr']) + + +class BusShiftFactory(factory.django.DjangoModelFactory): + name = factory.LazyFunction(fake.user_name) + + class Meta: + model = models.BusShift diff --git a/padam_django/apps/BusShift/management/__init__.py b/padam_django/apps/BusShift/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/padam_django/apps/BusShift/management/commands/__init__.py b/padam_django/apps/BusShift/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/padam_django/apps/BusShift/management/commands/create_busshift.py b/padam_django/apps/BusShift/management/commands/create_busshift.py new file mode 100644 index 00000000..1e8cd554 --- /dev/null +++ b/padam_django/apps/BusShift/management/commands/create_busshift.py @@ -0,0 +1,13 @@ +from padam_django.apps.common.management.base import CreateDataBaseCommand + +from padam_django.apps.BusShift.factories import BusShiftFactory + + +class Command(CreateDataBaseCommand): + + help = 'Create few shift' + + def handle(self, *args, **options): + super().handle(*args, **options) + self.stdout.write(f'Creating {self.number} shift ...') + BusShiftFactory.create_batch(size=self.number) diff --git a/padam_django/apps/BusShift/migrations/__init__.py b/padam_django/apps/BusShift/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/padam_django/apps/BusShift/models.py b/padam_django/apps/BusShift/models.py new file mode 100644 index 00000000..c72d433c --- /dev/null +++ b/padam_django/apps/BusShift/models.py @@ -0,0 +1,12 @@ +from django.db import models + + +class BusShift(models.Model): + name = models.CharField("Name of the Busshift", + max_length=100, default="Test") + + class Meta: + verbose_name_plural = "BusShift" + + def __str__(self): + return f"BusShift: {self.name}" diff --git a/padam_django/settings.py b/padam_django/settings.py index 129e922c..8ee75741 100644 --- a/padam_django/settings.py +++ b/padam_django/settings.py @@ -45,6 +45,7 @@ 'padam_django.apps.fleet', 'padam_django.apps.geography', 'padam_django.apps.users', + 'padam_django.apps.BusShift', ] MIDDLEWARE = [ From 75c1b4f18b34d105f172ea87a4eef252e9a16cd1 Mon Sep 17 00:00:00 2001 From: Damien Date: Wed, 12 Jun 2024 12:28:22 +0200 Subject: [PATCH 2/3] Add Busshift command to create_data --- padam_django/apps/common/management/commands/create_data.py | 1 + 1 file changed, 1 insertion(+) diff --git a/padam_django/apps/common/management/commands/create_data.py b/padam_django/apps/common/management/commands/create_data.py index a149a937..15a37e5b 100644 --- a/padam_django/apps/common/management/commands/create_data.py +++ b/padam_django/apps/common/management/commands/create_data.py @@ -12,3 +12,4 @@ def handle(self, *args, **options): management.call_command('create_drivers', number=5) management.call_command('create_buses', number=10) management.call_command('create_places', number=30) + management.call_command('create_busshift', number=2) From 1bb9b984c217443cadac2b1140e6e6a1aca2241d Mon Sep 17 00:00:00 2001 From: Damien Date: Thu, 13 Jun 2024 12:39:49 +0200 Subject: [PATCH 3/3] Bushift setup --- padam_django/apps/BusShift/admin.py | 12 +++-- padam_django/apps/BusShift/factories.py | 18 ++++++- padam_django/apps/BusShift/models.py | 70 +++++++++++++++++++++++-- 3 files changed, 92 insertions(+), 8 deletions(-) diff --git a/padam_django/apps/BusShift/admin.py b/padam_django/apps/BusShift/admin.py index f2b82245..3cd6afcd 100644 --- a/padam_django/apps/BusShift/admin.py +++ b/padam_django/apps/BusShift/admin.py @@ -1,8 +1,14 @@ from django.contrib import admin -from . import models +from padam_django.apps.BusShift.models import BusShift -@admin.register(models.BusShift) +@admin.register(BusShift) class BusShiftAdmin(admin.ModelAdmin): - pass + list_display = ('bus', 'driver', + 'shift_start', 'shift_end', 'duration') + filter_horizontal = ('places',) + search_fields = ('BusShiftname', 'bus__name', 'driver__name') + + def duration(self, obj): + return obj.duration diff --git a/padam_django/apps/BusShift/factories.py b/padam_django/apps/BusShift/factories.py index c8d78a0a..bc4537bf 100644 --- a/padam_django/apps/BusShift/factories.py +++ b/padam_django/apps/BusShift/factories.py @@ -3,12 +3,28 @@ from . import models +from padam_django.apps.fleet.factories import BusFactory, DriverFactory fake = Faker(['fr']) class BusShiftFactory(factory.django.DjangoModelFactory): - name = factory.LazyFunction(fake.user_name) + + BusShiftname = factory.LazyFunction(fake.name) + driver = factory.SubFactory(DriverFactory) + bus = factory.SubFactory(BusFactory) + + shift_start = factory.LazyFunction(fake.date_time_this_year) + shift_end = factory.LazyAttribute( + lambda o: o.shift_start + fake.time_delta()) + + @factory.post_generation + def places(self, create, extracted, **kwargs): + if not create: + return + if extracted: + for place in extracted: + self.places.add(place) class Meta: model = models.BusShift diff --git a/padam_django/apps/BusShift/models.py b/padam_django/apps/BusShift/models.py index c72d433c..0fb7ffae 100644 --- a/padam_django/apps/BusShift/models.py +++ b/padam_django/apps/BusShift/models.py @@ -1,12 +1,74 @@ from django.db import models +from django.core.exceptions import ValidationError + +from padam_django.apps.fleet.models import Bus, Driver +from padam_django.apps.geography.models import Place + +from datetime import datetime, timedelta +from django.utils import timezone class BusShift(models.Model): - name = models.CharField("Name of the Busshift", - max_length=100, default="Test") + BusShiftname = models.CharField("Name of the Bus Shift", + max_length=100, default="Shift") + + bus = models.ForeignKey(Bus, on_delete=models.CASCADE) + driver = models.ForeignKey(Driver, on_delete=models.CASCADE) + + shift_start = models.DateTimeField(default=timezone.now()) + shift_end = models.DateTimeField( + default=timezone.now() + timedelta(hours=8)) + + places = models.ManyToManyField(Place, related_name='bus_shifts') + + @property + def duration(self): + return self.shift_end - self.shift_start class Meta: - verbose_name_plural = "BusShift" + verbose_name_plural = "Bus Shifts" def __str__(self): - return f"BusShift: {self.name}" + return f"Bus Shift: {self.BusShiftname}" + + def clean(self): + # Validate that the bus is not already assigned to another shift during the same period + overlapping_shifts = BusShift.objects.filter( + bus=self.bus, + shift_start__lt=self.shift_end, + shift_end__gt=self.shift_start + ).exclude(id=self.id) + if overlapping_shifts.exists(): + raise ValidationError( + 'This bus is already assigned to another shift during the selected time period.') + + # Validate that the driver is not already assigned to another shift during the same period + overlapping_shifts = BusShift.objects.filter( + driver=self.driver, + shift_start__lt=self.shift_end, + shift_end__gt=self.shift_start + ).exclude(id=self.id) + if overlapping_shifts.exists(): + raise ValidationError( + 'This driver is already assigned to another shift during the selected time period.') + + def save(self, *args, **kwargs): + self.clean() # Ensure clean is called to validate before saving + super().save(*args, **kwargs) + + +# class BusStops(models.Model): + +# bus_line = models.CharField(max_length=100, default="line_test") + +# place = models.ForeignKey(Place, on_delete=models.CASCADE) + +# scheduled_time = models.DateTimeField(default=datetime.now()) +# order = models.PositiveIntegerField(default=1) + +# class Meta: +# ordering = ['order'] +# unique_together = ('bus_line', 'order') + +# def __str__(self): +# return f"{self.place} at {self.scheduled_time}"