from django.db import models from django.contrib.auth.models import User from django.db.models.signals import post_save from django.dispatch import receiver from django.utils.translation import gettext_lazy as _ class Profile(models.Model): ROLE_CHOICES = ( ('SHIPPER', _('Shipper (Need Goods Moved)')), ('TRUCK_OWNER', _('Truck Owner (Service Provider)')), ('ADMIN', _('Administrator')), ) user = models.OneToOneField(User, on_delete=models.CASCADE) role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='SHIPPER') phone_number = models.CharField(max_length=20, blank=True) def __str__(self): return f"{self.user.username} - {self.role}" class Truck(models.Model): owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='trucks') truck_type = models.CharField(_('Truck Type'), max_length=100) model = models.CharField(_('Model'), max_length=100) year = models.PositiveIntegerField(_('Year')) plate_no = models.CharField(_('Plate No'), max_length=50) load_capacity = models.CharField(_('Load Capacity'), max_length=100) color = models.CharField(_('Color'), max_length=50) # Pictures truck_picture = models.ImageField(_('Truck Picture'), upload_to='trucks/', blank=True, null=True) registration_front = models.ImageField(_('Registration Front'), upload_to='docs/', blank=True, null=True) registration_back = models.ImageField(_('Registration Back'), upload_to='docs/', blank=True, null=True) driver_license = models.ImageField(_('Driver License'), upload_to='docs/', blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"{self.truck_type} - {self.plate_no}" class Shipment(models.Model): STATUS_CHOICES = ( ('OPEN', _('Open for Bids')), ('IN_PROGRESS', _('In Progress')), ('COMPLETED', _('Completed')), ('CANCELLED', _('Cancelled')), ) shipper = models.ForeignKey(User, on_delete=models.CASCADE, related_name='shipments') description = models.TextField(_('Goods Description')) weight = models.CharField(_('Weight/Volume'), max_length=100) origin = models.CharField(_('Origin'), max_length=255) destination = models.CharField(_('Destination'), max_length=255) delivery_date = models.DateField(_('Requested Delivery Date')) status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='OPEN') assigned_truck = models.ForeignKey(Truck, on_delete=models.SET_NULL, null=True, blank=True, related_name='assigned_shipments') created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"{self.origin} to {self.destination} - {self.status}" class Bid(models.Model): STATUS_CHOICES = ( ('PENDING', _('Pending')), ('ACCEPTED', _('Accepted')), ('REJECTED', _('Rejected')), ) shipment = models.ForeignKey(Shipment, on_delete=models.CASCADE, related_name='bids') truck_owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='bids') truck = models.ForeignKey(Truck, on_delete=models.CASCADE) amount = models.DecimalField(_('Offer Amount'), max_digits=10, decimal_places=2) comments = models.TextField(_('Comments'), blank=True) status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='PENDING') created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"Bid by {self.truck_owner.username} for {self.shipment}" class Message(models.Model): shipment = models.ForeignKey(Shipment, on_delete=models.CASCADE, related_name='messages') sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sent_messages') content = models.TextField() timestamp = models.DateTimeField(auto_now_add=True) def __str__(self): return f"From {self.sender.username} at {self.timestamp}" @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): if hasattr(instance, 'profile'): instance.profile.save() else: Profile.objects.create(user=instance)