From 8ea3df3fab7c9199bf26ad67ca70eaaa2470b19a Mon Sep 17 00:00:00 2001 From: vignesh Date: Wed, 14 Oct 2026 21:51:31 +0530 Subject: [PATCH] feat(tracking): store logistics ETA internally in ShipmentTracking and PickupSchedule database --- shipping/__pycache__/models.cpython-314.pyc | Bin 6233 -> 7950 bytes shipping/__pycache__/views.cpython-314.pyc | Bin 73791 -> 75864 bytes .../0004_shipmenttracking_and_more.py | 38 ++++++++++++++++++ ..._shipmenttracking_and_more.cpython-314.pyc | Bin 0 -> 2224 bytes shipping/models.py | 21 ++++++++++ shipping/views.py | 37 ++++++++++++++++- 6 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 shipping/migrations/0004_shipmenttracking_and_more.py create mode 100644 shipping/migrations/__pycache__/0004_shipmenttracking_and_more.cpython-314.pyc diff --git a/shipping/__pycache__/models.cpython-314.pyc b/shipping/__pycache__/models.cpython-314.pyc index e191f6027dba67a287a35f90d4ec11f9b04cf983..c30725281d18412126f340df62cd105e92d72013 100644 GIT binary patch delta 1538 zcmZuxT})e59KWYu(9-tOdwY9Jp`)71wjP+O)ne**2%K@(de;jzfKcRw&uPF$EV3-@Q zlFwsn9GOK@s1UpF>qnccONszKDLvD* zX(LW>LVO%9acJYv4zS7ImQJAw_MLReZo+wDTa`_OF0At6wN1!|d@rq+Ov71$@vupMDb%*sA;9`zt>YnG`6WF5X?Y{v*YV%7(qXe+Rt z_7>b4voO)sBO4$^*ovJ^I~VsU{+Da3`}&}+>1z6NbJp2p*-cl(pAbQ*ty%i^gl(di z{o+zZceB<~gDZNPoLsNJ7wRuI>+i?yP=5vcXaMT3VhQRm*V->%Gjj{j$CE@)&YPLp z$pLG<18R=NjQPr9ikyc~iO7NHk{BFP05zAH(J0X~d6N<^5N`4^mtEj6%a}CWXHY9f zLofr_LhaZJ7ussdqZhI}(qr~F!N_2$-0k8ug6y{5y~fVSG4_r-#Fk{aXmtz24(?#Z z*>Dgclc2leOhg7FW0Rw&A}iMTiBWj{djIj(BP$%D0C_$c{UpNAg8;Q)!%HLXAx+Cu zqG_`r&7TBV7506h4@at<(c7KTljYFyji)#07lqBjMrP-H$*7L&x5xGB_*@zOsk!pl zd|6DFThpYQ-=PA;2ZC(f(_MUI9K6XzLimRxPj$MOufJo>n=_O1(Ep3Mdgs?1Sz^wb znOd8X%2P9=Q!|?(H@N2lK&_4FOIl7}PG@z4jB>g;CZvZSd5q)`hqLUo*FR9?TMpB( z^7jG$yvZY!f>o(^PwL%B?i|_mSEM-mI51RHI;%?Gp3=7^@1!fr#nt%!|IJw07TSME z^IVCRpP#NMS3un(S3Ti9Pk2M#I#=qgc*a)8AHK?8A{FVv>cxM#ku6%0P6Ojpt3LL( zcR*P{zYEB|fF9(Nzj}P2h3%@n4nEeT$bM79u6JR}E1Snm3JxC&qh~F*rq-{nUA-sp X{k=2DhZfMS>+6NJ!XE1Lo7oHV-Q0LQ=EATvlv4@gC0YWgg;{m%jAawlAAa1 zuVZ9Xo6IOA&d(CWZw}M~0wp4`tdkEiiHXFD1u+E)z=g$QSpy8fiUrLXp-LrTV#Y#n zF)2|7MTQ_@afTof6PS_GL89UeB{D%`C9+`*C2~RHKo3Yx_7+l8(qt*(1R7Q(2qL&a zgeQ==#p&Ye++m0|Q{nh-WUW@5}Y1`xYQ9w-L@9I|IX diff --git a/shipping/__pycache__/views.cpython-314.pyc b/shipping/__pycache__/views.cpython-314.pyc index 6265873cf1641169d589e2aeeca515fb90886d08..f399066638a9d525e6a3e8108e5bf46da37fa4e6 100644 GIT binary patch delta 10989 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 delta 9787 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 C3OQr| literal 0 HcmV?d00001 diff --git a/shipping/models.py b/shipping/models.py index 36e3ba6..ef5682a 100644 --- a/shipping/models.py +++ b/shipping/models.py @@ -71,6 +71,7 @@ class PickupSchedule(models.Model): pickup_location = models.CharField(max_length=150, blank=True, default='') status = models.CharField(max_length=50, choices=STATUS_CHOICES, default='SCHEDULED') expected_package_count = models.IntegerField(default=1) + expected_delivery_date = models.CharField(max_length=100, blank=True, null=True, default='') notes = models.TextField(blank=True, default='') raw_response = models.JSONField(default=dict, blank=True) created_at = models.DateTimeField(auto_now_add=True) @@ -82,3 +83,23 @@ class PickupSchedule(models.Model): def __str__(self): return f"[{self.carrier}] Pickup {self.pickup_id or 'Pending'} - AWB: {self.tracking_id} on {self.pickup_date} ({self.pickup_time})" + +class ShipmentTracking(models.Model): + tracking_id = models.CharField(max_length=100, unique=True, db_index=True) + client_order_id = models.CharField(max_length=100, blank=True, default='', db_index=True) + carrier = models.CharField(max_length=50, default='DELHIVERY', db_index=True) + current_status = models.CharField(max_length=100, default='in_transit') + expected_delivery_date = models.CharField(max_length=100, blank=True, null=True, default='') + picked_up_date = models.CharField(max_length=100, blank=True, null=True, default='') + origin = models.CharField(max_length=150, blank=True, default='') + destination = models.CharField(max_length=150, blank=True, default='') + raw_payload = models.JSONField(default=dict, blank=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + ordering = ['-updated_at'] + + def __str__(self): + return f"Shipment {self.tracking_id} [{self.carrier}] - ETA: {self.expected_delivery_date or 'N/A'}" + diff --git a/shipping/views.py b/shipping/views.py index 3c90cb7..64dbc08 100644 --- a/shipping/views.py +++ b/shipping/views.py @@ -8,7 +8,7 @@ from django.http import JsonResponse, HttpResponse from django.views.decorators.csrf import csrf_exempt from django.db.models import Q -from .models import ActivityLog, RiderAssignment +from .models import ActivityLog, RiderAssignment, PickupSchedule, ShipmentTracking from .sfx_client import execute_sfx_call, get_base_url, get_default_token from ekart.client import EkartAPIClient @@ -557,6 +557,20 @@ def webhook_listener_api(request): } ) saved_rider_id = rider_obj.id + + # Save ETA to DB if present in webhook payload + eta_wh = b_data.get('expected_delivery_date') or b_data.get('eta') or (b_data.get('order_details') or {}).get('expected_delivery_date') + if awb and eta_wh: + ShipmentTracking.objects.update_or_create( + tracking_id=str(awb).strip(), + defaults={ + 'client_order_id': str(client_ord).strip(), + 'current_status': str(st).strip(), + 'expected_delivery_date': str(eta_wh).strip(), + 'raw_payload': b_data + } + ) + PickupSchedule.objects.filter(tracking_id=str(awb).strip()).update(expected_delivery_date=str(eta_wh).strip()) except Exception as parse_err: pass @@ -729,6 +743,27 @@ def api_forward_router(request, action_name): 'timestamp': scan_detail.get('ScanDateTime') or scan_detail.get('StatusDateTime') }) norm_curr = 'delivered' if 'delivered' in curr_st.lower() else ('out_for_delivery' if 'out for delivery' in curr_st.lower() else ('in_transit' if 'transit' in curr_st.lower() or any(h['status'] == 'picked_up' for h in formatted_history) else curr_st.lower().replace(' ', '_'))) + eta_val = ship.get('ExpectedDeliveryDate') + + # Persist ETA & tracking internally to DB + try: + ShipmentTracking.objects.update_or_create( + tracking_id=awb_str, + defaults={ + 'carrier': 'DELHIVERY', + 'current_status': norm_curr, + 'expected_delivery_date': str(eta_val or ''), + 'picked_up_date': str(ship.get('PickedupDate') or ship.get('PickUpDate') or ''), + 'origin': str(ship.get('Origin') or ''), + 'destination': str(ship.get('Destination') or ''), + 'raw_payload': ship + } + ) + if eta_val: + PickupSchedule.objects.filter(tracking_id=awb_str).update(expected_delivery_date=str(eta_val)) + except Exception: + pass + return JsonResponse({ 'status': 'success', 'carrier': 'Delhivery Logistics',