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 _ from django.utils.translation import get_language 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') # English fields truck_type = models.CharField(_('Truck Type (EN)'), max_length=100) model = models.CharField(_('Model (EN)'), max_length=100) load_capacity = models.CharField(_('Load Capacity (EN)'), max_length=100) color = models.CharField(_('Color (EN)'), max_length=50) # Arabic fields truck_type_ar = models.CharField(_('Truck Type (AR)'), max_length=100, blank=True) model_ar = models.CharField(_('Model (AR)'), max_length=100, blank=True) load_capacity_ar = models.CharField(_('Load Capacity (AR)'), max_length=100, blank=True) color_ar = models.CharField(_('Color (AR)'), max_length=50, blank=True) year = models.PositiveIntegerField(_('Year')) plate_no = models.CharField(_('Plate No'), max_length=50) registration_expiry_date = models.DateField(_('Registration Expiry Date'), null=True, blank=True) # 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) is_approved = models.BooleanField(_('Is Approved'), default=False) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"{self.display_truck_type} - {self.plate_no}" @property def display_truck_type(self): if get_language() == 'ar' and self.truck_type_ar: return self.truck_type_ar return self.truck_type @property def display_model(self): if get_language() == 'ar' and self.model_ar: return self.model_ar return self.model @property def display_load_capacity(self): if get_language() == 'ar' and self.load_capacity_ar: return self.load_capacity_ar return self.load_capacity @property def display_color(self): if get_language() == 'ar' and self.color_ar: return self.color_ar return self.color 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)