162 lines
4.7 KiB
Python
162 lines
4.7 KiB
Python
import os
|
|
import json
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
STATE_CODE_TO_NAME = {
|
|
'AN': 'Andaman and Nicobar Islands',
|
|
'AP': 'Andhra Pradesh',
|
|
'AR': 'Arunachal Pradesh',
|
|
'AS': 'Assam',
|
|
'BR': 'Bihar',
|
|
'CG': 'Chhattisgarh',
|
|
'CH': 'Chandigarh',
|
|
'DD': 'Daman and Diu',
|
|
'DL': 'Delhi',
|
|
'DN': 'Dadra and Nagar Haveli',
|
|
'GA': 'Goa',
|
|
'GJ': 'Gujarat',
|
|
'HP': 'Himachal Pradesh',
|
|
'HR': 'Haryana',
|
|
'JH': 'Jharkhand',
|
|
'JK': 'Jammu and Kashmir',
|
|
'KA': 'Karnataka',
|
|
'KL': 'Kerala',
|
|
'LA': 'Ladakh',
|
|
'MH': 'Maharashtra',
|
|
'ML': 'Meghalaya',
|
|
'MN': 'Manipur',
|
|
'MP': 'Madhya Pradesh',
|
|
'NL': 'Nagaland',
|
|
'OR': 'Odisha',
|
|
'PB': 'Punjab',
|
|
'PU': 'Puducherry',
|
|
'PY': 'Puducherry',
|
|
'RJ': 'Rajasthan',
|
|
'SK': 'Sikkim',
|
|
'TN': 'Tamil Nadu',
|
|
'TR': 'Tripura',
|
|
'TS': 'Telangana',
|
|
'UK': 'Uttarakhand',
|
|
'UP': 'Uttar Pradesh',
|
|
'WB': 'West Bengal'
|
|
}
|
|
|
|
_DELHIVERY_PINCODE_MAP = None
|
|
|
|
def _load_delhivery_database():
|
|
"""Lazily loads the official Delhivery pincode serviceability database."""
|
|
global _DELHIVERY_PINCODE_MAP
|
|
if _DELHIVERY_PINCODE_MAP is not None:
|
|
return _DELHIVERY_PINCODE_MAP
|
|
|
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
json_path = os.path.join(current_dir, 'data', 'delhivery_pincodes.json')
|
|
|
|
if not os.path.exists(json_path):
|
|
logger.warning(f"Delhivery pincode database not found at {json_path}")
|
|
_DELHIVERY_PINCODE_MAP = {}
|
|
return _DELHIVERY_PINCODE_MAP
|
|
|
|
try:
|
|
with open(json_path, 'r', encoding='utf-8') as f:
|
|
_DELHIVERY_PINCODE_MAP = json.load(f)
|
|
logger.info(f"Loaded {len(_DELHIVERY_PINCODE_MAP)} official Delhivery serviceable pincodes into memory.")
|
|
except Exception as e:
|
|
logger.error(f"Error loading Delhivery pincode database: {e}")
|
|
_DELHIVERY_PINCODE_MAP = {}
|
|
|
|
return _DELHIVERY_PINCODE_MAP
|
|
|
|
|
|
def get_delhivery_pincode_info(pincode):
|
|
"""
|
|
Returns full official Delhivery serviceability metadata for a 6-digit pincode.
|
|
Schema returned:
|
|
{
|
|
"pincode": "600001",
|
|
"state_code": "TN",
|
|
"state": "Tamil Nadu",
|
|
"city": "Chennai",
|
|
"district": "Chennai",
|
|
"prepaid": True,
|
|
"cod": True,
|
|
"reverse_pickup": True,
|
|
"repl": True,
|
|
"cash": True,
|
|
"serviceable": True
|
|
}
|
|
"""
|
|
db = _load_delhivery_database()
|
|
pin_str = str(pincode or "").strip()
|
|
if not pin_str or pin_str not in db:
|
|
return None
|
|
|
|
entry = db[pin_str]
|
|
# format: [state_code, district, prepaid, cod, rev_pickup, repl, cash]
|
|
st_code = entry[0]
|
|
district = entry[1]
|
|
prepaid = bool(entry[2])
|
|
cod = bool(entry[3])
|
|
rev_pickup = bool(entry[4]) if len(entry) > 4 else True
|
|
repl = bool(entry[5]) if len(entry) > 5 else True
|
|
cash = bool(entry[6]) if len(entry) > 6 else True
|
|
|
|
st_name = STATE_CODE_TO_NAME.get(st_code, st_code)
|
|
|
|
return {
|
|
"pincode": pin_str,
|
|
"state_code": st_code,
|
|
"state": st_name,
|
|
"city": district,
|
|
"district": district,
|
|
"prepaid": prepaid,
|
|
"cod": cod,
|
|
"reverse_pickup": rev_pickup,
|
|
"repl": repl,
|
|
"cash": cash,
|
|
"serviceable": True
|
|
}
|
|
|
|
|
|
def is_delhivery_serviceable(pincode, is_cod=False):
|
|
"""
|
|
Validates whether a pincode is serviceable by Delhivery.
|
|
Returns (serviceable: bool, reason: str, info: dict or None).
|
|
"""
|
|
info = get_delhivery_pincode_info(pincode)
|
|
if not info:
|
|
return False, f"Pincode {pincode} is not serviceable by Delhivery.", None
|
|
|
|
if is_cod and not info['cod']:
|
|
return False, f"COD payment mode is not serviceable by Delhivery for pincode {pincode}.", info
|
|
|
|
return True, "Serviceable", info
|
|
|
|
|
|
def check_delhivery_route_serviceability(pickup_pincode, drop_pincode, is_cod=False):
|
|
"""
|
|
Checks if both pickup and drop locations are serviceable by Delhivery.
|
|
Returns (serviceable: bool, reason: str, drop_info: dict, pickup_info: dict).
|
|
"""
|
|
drop_ok, drop_msg, drop_info = is_delhivery_serviceable(drop_pincode, is_cod=is_cod)
|
|
if not drop_ok:
|
|
return False, f"Destination: {drop_msg}", None, None
|
|
|
|
pickup_ok, pickup_msg, pickup_info = is_delhivery_serviceable(pickup_pincode, is_cod=False)
|
|
if not pickup_ok:
|
|
return False, f"Pickup: {pickup_msg}", drop_info, None
|
|
|
|
return True, "Route is serviceable by Delhivery", drop_info, pickup_info
|
|
|
|
|
|
def resolve_delhivery_location(pincode):
|
|
"""
|
|
Resolves official (City, State) from Delhivery database.
|
|
Returns (city, state) or None.
|
|
"""
|
|
info = get_delhivery_pincode_info(pincode)
|
|
if info:
|
|
return info['city'], info['state']
|
|
return None
|