Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entrypoint.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ echo "Running migrate..."
python manage.py migrate --noinput

echo "Starting Django server on port ${DJANGO_PORT}..."
python manage.py runserver 0.0.0.0:${DJANGO_PORT}
python manage.py runserver 0.0.0.0:${DJANGO_PORT} || python manage.py runserver 8001
6 changes: 3 additions & 3 deletions fleet/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
@admin.register(Vehicle)
class VehicleAdmin(admin.ModelAdmin):
list_display = (
'vehicle_id', 'name', 'capacity', 'status', 'fuel_type',
'vehicle_id', 'model', 'capacity', 'status', 'fuel_type',
'depot_id', 'depot_latitude', 'depot_longitude', 'last_location_update'
)
list_filter = ('status', 'fuel_type')
search_fields = ('vehicle_id', 'name', 'plate_number', 'depot_id')
search_fields = ('vehicle_id', 'model', 'plate_number', 'depot_id')
readonly_fields = ('created_at', 'updated_at', 'last_location_update')

fieldsets = (
('Basic Information', {
'fields': (
'vehicle_id', 'name', 'plate_number',
'vehicle_id', 'model', 'plate_number',
'year_of_manufacture', 'status'
)
}),
Expand Down
22 changes: 22 additions & 0 deletions fleet/migrations/0006_remove_vehicle_name_vehicle_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.2.1 on 2025-05-17 08:39

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('fleet', '0005_vehicle_depot_latitude_vehicle_depot_longitude'),
]

operations = [
migrations.RemoveField(
model_name='vehicle',
name='name',
),
migrations.AddField(
model_name='vehicle',
name='model',
field=models.CharField(blank=True, max_length=100),
),
]
18 changes: 18 additions & 0 deletions fleet/migrations/0007_vehicle_driver_assigned.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.2.1 on 2025-05-17 10:31

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('fleet', '0006_remove_vehicle_name_vehicle_model'),
]

operations = [
migrations.AddField(
model_name='vehicle',
name='driver_assigned',
field=models.BooleanField(default=False, help_text='Indicates if a driver is assigned to this vehicle'),
),
]
5 changes: 4 additions & 1 deletion fleet/models/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Vehicle(models.Model):
]

vehicle_id = models.CharField(max_length=20, unique=True)
name = models.CharField(max_length=100, blank=True)
model = models.CharField(max_length=100, blank=True)
capacity = models.PositiveIntegerField(help_text="Capacity in kilograms")
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='available')
fuel_type = models.CharField(max_length=20, choices=FUEL_TYPE_CHOICES, default='diesel')
Expand Down Expand Up @@ -55,6 +55,9 @@ class Vehicle(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

# In Vehicle model
driver_assigned = models.BooleanField(default=False, help_text="Indicates if a driver is assigned to this vehicle")

def __str__(self):
return f"{self.vehicle_id} ({self.status})"

Expand Down
31 changes: 15 additions & 16 deletions fleet/serializers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
from .vehicle import VehicleSerializer, VehicleLocationSerializer
from .vehicle import (
VehicleSerializer,
VehicleSummarySerializer,
VehicleLocationDetailSerializer,
LocationPointSerializer
)

from django.conf import settings

# Always import base detail serializer
from .vehicle import VehicleDetailSerializer as BaseVehicleDetailSerializer

# If extended mode is enabled, override VehicleDetailSerializer
if settings.ENABLE_FLEET_EXTENDED_MODELS:
from .maintenance import (
MaintenanceRecordSerializer,
MaintenanceScheduleSerializer
)
from .fuel import FuelRecordSerializer
from .trip import TripRecordSerializer

from rest_framework import serializers

class VehicleDetailSerializer(VehicleSerializer):
class VehicleDetailSerializer(BaseVehicleDetailSerializer):
maintenance_records = MaintenanceRecordSerializer(many=True, read_only=True)
fuel_records = serializers.SerializerMethodField()
trip_records = serializers.SerializerMethodField()
location_history = serializers.SerializerMethodField()

class Meta(VehicleSerializer.Meta):
fields = VehicleSerializer.Meta.fields + [
'maintenance_records', 'fuel_records', 'trip_records', 'location_history'
class Meta(BaseVehicleDetailSerializer.Meta):
fields = BaseVehicleDetailSerializer.Meta.fields + [
'maintenance_records', 'fuel_records', 'trip_records'
]

def get_fuel_records(self, obj):
Expand All @@ -30,13 +37,5 @@ def get_fuel_records(self, obj):
def get_trip_records(self, obj):
records = obj.trip_records.all()[:5]
return TripRecordSerializer(records, many=True).data

def get_location_history(self, obj):
records = obj.location_history.all()[:10]
return VehicleLocationSerializer(records, many=True).data

else:
class VehicleDetailSerializer(VehicleSerializer):
"""Fallback when extended models are disabled."""
class Meta(VehicleSerializer.Meta):
fields = VehicleSerializer.Meta.fields
VehicleDetailSerializer = BaseVehicleDetailSerializer
68 changes: 63 additions & 5 deletions fleet/serializers/vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Meta:
fields = [
'id',
'vehicle_id',
'name',
'model',
'capacity',
'status',
'fuel_type',
Expand All @@ -28,12 +28,70 @@ class Meta:
'created_at',
'updated_at',
'is_available',
'location_is_stale'
'location_is_stale',
'driver_assigned'
]
read_only_fields = ['created_at', 'updated_at', 'last_location_update']


class VehicleLocationSerializer(serializers.ModelSerializer):
class LocationPointSerializer(serializers.Serializer):
latitude = serializers.DecimalField(max_digits=9, decimal_places=6)
longitude = serializers.DecimalField(max_digits=9, decimal_places=6)
location_name = serializers.CharField()
timestamp = serializers.DateTimeField()


class VehicleLocationDetailSerializer(serializers.Serializer):
plate_number = serializers.CharField()
truck_id = serializers.CharField(source='vehicle_id')
model = serializers.CharField()
status = serializers.SerializerMethodField()

def get_status(self, obj):
history_qs = VehicleLocation.objects.filter(vehicle=obj).order_by('-timestamp')
current_location = None
location_history = []

for i, loc in enumerate(history_qs):
loc_data = {
'latitude': loc.latitude,
'longitude': loc.longitude,
'timestamp': loc.timestamp,
'location_name': self.get_mock_location_name(loc.latitude, loc.longitude)
}

if i == 0:
current_location = loc_data
else:
location_history.append(loc_data)

return {
"current_location": current_location,
"location_history": location_history
}

def get_mock_location_name(self, lat, lon):
# This should be replaced with a geocoding service if needed
if lat > 6.926:
return "Colombo Fort"
elif lat > 6.923:
return "Slave Island"
elif lat > 6.921:
return "Kollupitiya"
else:
return "Bambalapitiya"

# 🔹 Base serializer for all cases
class VehicleDetailSerializer(VehicleSerializer):
location_detail = serializers.SerializerMethodField()

class Meta(VehicleSerializer.Meta):
fields = VehicleSerializer.Meta.fields + ['location_detail']

def get_location_detail(self, obj):
return VehicleLocationDetailSerializer(obj).data

class VehicleSummarySerializer(serializers.ModelSerializer):
class Meta:
model = VehicleLocation
fields = ['timestamp', 'latitude', 'longitude', 'speed', 'heading']
model = Vehicle
fields = ['vehicle_id', 'plate_number', 'model', 'status']
4 changes: 2 additions & 2 deletions fleet/tests/test_vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class VehicleModelTest(TestCase):
def setUp(self):
self.vehicle = Vehicle.objects.create(
vehicle_id="TRK001",
name="Test Truck 1",
model="Test Truck 1",
capacity=1000,
status="available",
fuel_type="diesel",
Expand All @@ -22,7 +22,7 @@ def test_vehicle_fields_and_defaults(self):
"""Test vehicle creation and default values."""
v = self.vehicle
self.assertEqual(v.vehicle_id, "TRK001")
self.assertEqual(v.name, "Test Truck 1")
self.assertEqual(v.model, "Test Truck 1")
self.assertEqual(v.capacity, 1000)
self.assertEqual(v.status, "available")
self.assertEqual(v.fuel_type, "diesel")
Expand Down
Loading
Loading