Coverage for modules\trucking\models\delivery.py: 97%

35 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-09-06 16:58 +0800

1from django.db import models 

2from decimal import Decimal 

3from core.models import TenantScopedModel 

4 

5 

6class Delivery(TenantScopedModel): 

7 """Individual delivery within a trip.""" 

8 

9 STATUS_CHOICES = [ 

10 ("PENDING", "Pending"), 

11 ("PICKED_UP", "Picked Up"), 

12 ("IN_TRANSIT", "In Transit"), 

13 ("OUT_FOR_DELIVERY", "Out for Delivery"), 

14 ("DELIVERED", "Delivered"), 

15 ("FAILED", "Failed Delivery"), 

16 ("RETURNED", "Returned"), 

17 ] 

18 

19 PRIORITY_CHOICES = [ 

20 ("LOW", "Low"), 

21 ("NORMAL", "Normal"), 

22 ("HIGH", "High"), 

23 ("URGENT", "Urgent"), 

24 ] 

25 

26 trip = models.ForeignKey( 

27 "Trip", on_delete=models.CASCADE, related_name="deliveries", null=True, blank=True 

28 ) 

29 tracking_number = models.CharField(max_length=64, unique=True, db_index=True) 

30 

31 # Recipient info 

32 recipient_name = models.CharField(max_length=128) 

33 recipient_phone = models.CharField(max_length=32, blank=True, null=True) 

34 recipient_email = models.EmailField(blank=True, null=True) 

35 

36 # Address 

37 delivery_address = models.TextField() 

38 city = models.CharField(max_length=128) 

39 province = models.CharField(max_length=128, blank=True, null=True) 

40 postal_code = models.CharField(max_length=20, blank=True, null=True) 

41 country = models.CharField(max_length=64, default="Philippines") 

42 

43 # Package details 

44 package_description = models.TextField(blank=True, null=True) 

45 package_weight_kg = models.DecimalField(max_digits=10, decimal_places=2, default=Decimal("0.00")) 

46 number_of_packages = models.IntegerField(default=1) 

47 

48 # Status and priority 

49 status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="PENDING") 

50 priority = models.CharField(max_length=10, choices=PRIORITY_CHOICES, default="NORMAL") 

51 

52 # Timing 

53 scheduled_date = models.DateField(null=True, blank=True) 

54 scheduled_time_window_start = models.TimeField(null=True, blank=True) 

55 scheduled_time_window_end = models.TimeField(null=True, blank=True) 

56 actual_delivery_time = models.DateTimeField(null=True, blank=True) 

57 

58 # Proof of delivery 

59 signature_url = models.URLField(blank=True, null=True) 

60 photo_urls = models.JSONField(default=list, blank=True) 

61 delivery_notes = models.TextField(blank=True, null=True) 

62 recipient_signature_name = models.CharField(max_length=128, blank=True, null=True) 

63 

64 # Reference 

65 reference_number = models.CharField(max_length=64, blank=True, null=True) 

66 proof_of_delivery_received = models.BooleanField(default=False) 

67 

68 class Meta: 

69 ordering = ["-created_at"] 

70 

71 def __str__(self): 

72 return f"Delivery {self.tracking_number}: {self.recipient_name}"