| Line 36... |
Line 36... |
| 36 |
from shop2020.thriftpy.crm.ttypes import *
|
36 |
from shop2020.thriftpy.crm.ttypes import *
|
| 37 |
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \
|
37 |
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \
|
| 38 |
OrderStatus
|
38 |
OrderStatus
|
| 39 |
from shop2020.utils.EmailAttachmentSender import get_attachment_part, mail
|
39 |
from shop2020.utils.EmailAttachmentSender import get_attachment_part, mail
|
| 40 |
from shop2020.utils.Utils import to_py_date
|
40 |
from shop2020.utils.Utils import to_py_date
|
| 41 |
from xml.etree.ElementTree import parse
|
41 |
from xml.etree.ElementTree import parse, fromstring
|
| 42 |
import csv
|
42 |
import csv
|
| 43 |
import datetime
|
43 |
import datetime
|
| 44 |
import json
|
44 |
import json
|
| 45 |
import optparse
|
45 |
import optparse
|
| 46 |
import re
|
46 |
import re
|
| Line 52... |
Line 52... |
| 52 |
|
52 |
|
| 53 |
if __name__ == '__main__' and __package__ is None:
|
53 |
if __name__ == '__main__' and __package__ is None:
|
| 54 |
import os
|
54 |
import os
|
| 55 |
sys.path.insert(0, os.getcwd())
|
55 |
sys.path.insert(0, os.getcwd())
|
| 56 |
|
56 |
|
| - |
|
57 |
REASON_CODES_PICKUP_REGISTERED = ['013']
|
| - |
|
58 |
REASON_CODES_SHIPMENT_ARRIVED = ['127', '0002']
|
| - |
|
59 |
REASON_CODES_UNDELIVERED_MAP = { '005':'Reached Destination City', '006':'Out for Delivery', '303': 'Shipment In Transit'}
|
| - |
|
60 |
REASON_CODES_NDR = ['200', '201', '202', '206', '207', '208', '209', '210', '212', '213', '214', '215', '216',
|
| - |
|
61 |
'217', '221', '222', '223', '224', '225', '226', '227', '228','229', '231', '232', '233',
|
| - |
|
62 |
'331','331','332','333','331','666','888','218', '219', '220', '1225'
|
| - |
|
63 |
]
|
| - |
|
64 |
REASON_CODES_DELIVERED=['999', '204']
|
| - |
|
65 |
REASON_CODES_RTO = ['777', '77', '80', '82', '83']
|
| 57 |
|
66 |
|
| 58 |
finalUpdateUrl = ""
|
67 |
finalUpdateUrl = ""
|
| 59 |
live = "false"
|
68 |
live = "false"
|
| 60 |
try:
|
69 |
try:
|
| 61 |
config_client = ConfigClient()
|
70 |
config_client = ConfigClient()
|
| Line 63... |
Line 72... |
| 63 |
except:
|
72 |
except:
|
| 64 |
live = "true"
|
73 |
live = "true"
|
| 65 |
|
74 |
|
| 66 |
if live=="true":
|
75 |
if live=="true":
|
| 67 |
UPDATE_URL = "http://plapi.ecomexpress.in/track_me/api/mawbd/?order=&"
|
76 |
UPDATE_URL = "http://plapi.ecomexpress.in/track_me/api/mawbd/?order=&"
|
| 68 |
ECOM_API_USERNAME = "ecomexpress"
|
77 |
ECOM_API_USERNAME = "newspice671445"
|
| 69 |
ECOM_API_PASSWORD = "Ke$3c@4oT5m6h%23$"
|
78 |
ECOM_API_PASSWORD = "npcs67unsd44debm"
|
| 70 |
else:
|
79 |
else:
|
| 71 |
UPDATE_URL = "http://staging.ecomexpress.in/track_me/api/mawbd/?order=&"
|
80 |
UPDATE_URL = "http://staging.ecomexpress.in/track_me/api/mawbd/?order=&"
|
| 72 |
ECOM_API_USERNAME = "ecomexpress"
|
81 |
ECOM_API_USERNAME = "ecomexpress"
|
| 73 |
ECOM_API_PASSWORD = "Ke$3c@4oT5m6h%23$"
|
82 |
ECOM_API_PASSWORD = "Ke$3c@4oT5m6h%23$"
|
| 74 |
|
83 |
|
| 75 |
finalUpdateUrl = UPDATE_URL + "username=" + ECOM_API_USERNAME + "&password="+ECOM_API_PASSWORD
|
84 |
finalUpdateUrl = UPDATE_URL + "username=" + ECOM_API_USERNAME + "&password="+ECOM_API_PASSWORD
|
| - |
|
85 |
|
| 76 |
|
86 |
|
| 77 |
|
87 |
|
| 78 |
defaultUndeliveredAsssigneeId = 65
|
88 |
defaultUndeliveredAsssigneeId = 65
|
| 79 |
dtrUndeliveredAsssigneeId = 33
|
89 |
dtrUndeliveredAsssigneeId = 33
|
| 80 |
from_user = 'cnc.center@shop2020.in'
|
90 |
from_user = 'cnc.center@shop2020.in'
|
| Line 103... |
Line 113... |
| 103 |
|
113 |
|
| 104 |
def process_pickup_records(provider):
|
114 |
def process_pickup_records(provider):
|
| 105 |
try:
|
115 |
try:
|
| 106 |
orders_tobe_picked_up = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH])
|
116 |
orders_tobe_picked_up = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH])
|
| 107 |
pickup_details = read_pickup_orders(orders_tobe_picked_up)
|
117 |
pickup_details = read_pickup_orders(orders_tobe_picked_up)
|
| - |
|
118 |
print "pickup_details", pickup_details
|
| 108 |
if pickup_details:
|
119 |
if pickup_details:
|
| 109 |
update_picked_orders(provider.id, pickup_details)
|
120 |
update_picked_orders(provider.id, pickup_details)
|
| 110 |
except:
|
121 |
except:
|
| 111 |
print "Some issue while processing the orders in SHIPPED_FROM_WH status"
|
122 |
print "Some issue while processing the orders in SHIPPED_FROM_WH status"
|
| 112 |
traceback.print_exc()
|
123 |
traceback.print_exc()
|
| Line 143... |
Line 154... |
| 143 |
|
154 |
|
| 144 |
def process_delivery_report(provider):
|
155 |
def process_delivery_report(provider):
|
| 145 |
try:
|
156 |
try:
|
| 146 |
orders_tobe_delivered = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE])
|
157 |
orders_tobe_delivered = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE])
|
| 147 |
delivered_orders, returned_orders, undelivered_orders = read_delivery_orders(orders_tobe_delivered)
|
158 |
delivered_orders, returned_orders, undelivered_orders = read_delivery_orders(orders_tobe_delivered)
|
| - |
|
159 |
print "delivey_orders", delivered_orders
|
| 148 |
if delivered_orders:
|
160 |
if delivered_orders:
|
| 149 |
update_delivered_orders(provider.id, delivered_orders)
|
161 |
update_delivered_orders(provider.id, delivered_orders)
|
| - |
|
162 |
print "returned_orders", returned_orders
|
| 150 |
if returned_orders:
|
163 |
if returned_orders:
|
| 151 |
update_returned_orders(provider.id, returned_orders)
|
164 |
update_returned_orders(provider.id, returned_orders)
|
| - |
|
165 |
print "undelivered_orders", undelivered_orders
|
| 152 |
if undelivered_orders:
|
166 |
if undelivered_orders:
|
| 153 |
update_reason_of_undelivered_orders(provider.id, undelivered_orders)
|
167 |
update_reason_of_undelivered_orders(provider.id, undelivered_orders)
|
| 154 |
except:
|
168 |
except:
|
| 155 |
print "Some issue while processing the orders for delivery status"
|
169 |
print "Some issue while processing the orders for delivery status"
|
| 156 |
traceback.print_exc()
|
170 |
traceback.print_exc()
|
| Line 352... |
Line 366... |
| 352 |
currentBatch = awbs[doneAwbs:doneAwbs+batchSize]
|
366 |
currentBatch = awbs[doneAwbs:doneAwbs+batchSize]
|
| 353 |
print "currentBatch", currentBatch
|
367 |
print "currentBatch", currentBatch
|
| 354 |
url = finalUpdateUrl + "&awb=" + ",".join(currentBatch)
|
368 |
url = finalUpdateUrl + "&awb=" + ",".join(currentBatch)
|
| 355 |
print url
|
369 |
print url
|
| 356 |
response = urllib2.urlopen(url)
|
370 |
response = urllib2.urlopen(url)
|
| 357 |
print response.read()
|
371 |
responseString = response.read()
|
| 358 |
return
|
- |
|
| 359 |
#print "RQUICK AWB response", response
|
372 |
print responseString
|
| 360 |
jsonResponse = json.loads(response.read())
|
373 |
root = fromstring(responseString)
|
| 361 |
print jsonResponse
|
374 |
print root.tag
|
| 362 |
if jsonResponse['status']!=1:
|
375 |
awbs = []
|
| 363 |
print "Invalid api status"
|
376 |
for awbEle in root:
|
| 364 |
else:
|
- |
|
| 365 |
for awbObj in jsonResponse['data']:
|
377 |
awbNumber = awbEle.findall("field/[@name='awb_number']")[0].text
|
| 366 |
for awb, awbResponse in awbObj.iteritems():
|
378 |
reasonCode = awbEle.findall("field/[@name='reason_code_number']")[0].text
|
| 367 |
awbDetails = awbResponse['response']
|
379 |
deliveryDate = awbEle.findall("field/[@name='delivery_date']")[0].text
|
| 368 |
awbStatuses[awb] = awbDetails
|
380 |
lastUpdateDate = awbEle.findall("field/[@name='last_update_date']")[0].text
|
| 369 |
doneAwbs += batchSize
|
381 |
xmlScans = awbEle.findall("field/object/[@model='scan_stages']")
|
| - |
|
382 |
awbStatuses[awbNumber] = {'awbNumber': awbNumber, 'reasonCode': reasonCode, 'deliveryDate':deliveryDate, 'lastUpdateDate':lastUpdateDate, 'scans': xmlScans}
|
| 370 |
|
383 |
|
| - |
|
384 |
doneAwbs += batchSize
|
| - |
|
385 |
print awbStatuses
|
| 371 |
|
386 |
|
| 372 |
return awbStatuses
|
387 |
return awbStatuses
|
| 373 |
|
388 |
|
| 374 |
|
389 |
|
| 375 |
|
390 |
|
| 376 |
class __AWBStatusObj:
|
391 |
class __AWBStatusObj:
|
| 377 |
def __init__(self, awb, status, statusDate):
|
392 |
def __init__(self, awb, statusCode, statusDescription, statusDate):
|
| 378 |
self.awb = awb
|
393 |
self.awb = awb
|
| 379 |
self.status = status
|
394 |
self.statusCode = statusCode
|
| - |
|
395 |
self.statusDescription = statusDescription
|
| 380 |
self.statusDate = statusDate
|
396 |
self.statusDate = statusDate
|
| - |
|
397 |
|
| - |
|
398 |
def __get_scan_by_code(xmlScans, codes):
|
| - |
|
399 |
awbStatusObj = None
|
| - |
|
400 |
for xmlScan in xmlScans:
|
| - |
|
401 |
reasonCodeNumber = xmlScan.findall("[@name='reason_code_number']")[0].text
|
| - |
|
402 |
if reasonCodeNumber in codes:
|
| - |
|
403 |
statusDescription = xmlScan.findall("[@name='status']")[0].text
|
| - |
|
404 |
statusDate = get_py_datetime(xmlScan.findall("[@name='updated_on']")[0].text)
|
| - |
|
405 |
awbStatusObj = __AWBStatusObj(None, reasonCodeNumber, statusDescription, statusDate)
|
| 381 |
|
406 |
|
| 382 |
|
407 |
return awbStatusObj
|
| 383 |
|
408 |
|
| 384 |
def read_pickup_orders(orders_tobe_picked_up):
|
409 |
def read_pickup_orders(orders_tobe_picked_up):
|
| 385 |
picked_up_orders = {}
|
410 |
picked_up_orders = {}
|
| 386 |
awbs = [order.airwaybill_no for order in orders_tobe_picked_up]
|
411 |
awbs = [order.airwaybill_no for order in orders_tobe_picked_up]
|
| 387 |
|
412 |
|
| 388 |
for awb, awbDetails in get_awb_status(awbs).iteritems():
|
413 |
for awb, awbDetails in get_awb_status(awbs).iteritems():
|
| - |
|
414 |
|
| 389 |
#status = awbDetails['Status']
|
415 |
xmlScans = awbDetails['xmlScans']
|
| 390 |
#statusDate = get_pawbDetails['StatusDateTime']
|
416 |
awbStatusObj = __get_scan_by_code(xmlScans, ['0011'])
|
| - |
|
417 |
|
| 391 |
print awbDetails
|
418 |
if awbStatusObj is None:
|
| 392 |
tracking = awbDetails['Tracking']
|
419 |
continue
|
| - |
|
420 |
|
| 393 |
bookedTime = get_py_datetime(tracking[-1]['StatusDateTime'])
|
421 |
bookedTime = awbStatusObj.statusDate
|
| 394 |
picked_up_orders[awb] = str(bookedTime)
|
422 |
picked_up_orders[awb] = str(bookedTime)
|
| - |
|
423 |
|
| 395 |
print "Picked up Orders:"
|
424 |
print "Picked up Orders:"
|
| 396 |
print picked_up_orders
|
425 |
print picked_up_orders
|
| 397 |
return picked_up_orders
|
426 |
return picked_up_orders
|
| 398 |
|
427 |
|
| 399 |
def read_local_connection_orders(orders_tobe_local_connected):
|
428 |
def read_local_connection_orders(orders_tobe_local_connected):
|
| Line 441... |
Line 470... |
| 441 |
undelivered_orders = {}
|
470 |
undelivered_orders = {}
|
| 442 |
|
471 |
|
| 443 |
awbs = [order.airwaybill_no for order in orders_tobe_delivered]
|
472 |
awbs = [order.airwaybill_no for order in orders_tobe_delivered]
|
| 444 |
|
473 |
|
| 445 |
for awb, awbDetails in get_awb_status(awbs).iteritems():
|
474 |
for awb, awbDetails in get_awb_status(awbs).iteritems():
|
| 446 |
status = awbDetails['Status']
|
475 |
xmlScans = awbDetails['xmlScans']
|
| - |
|
476 |
|
| - |
|
477 |
deliveredAwbStatusObj = __get_scan_by_code(xmlScans, REASON_CODES_DELIVERED)
|
| - |
|
478 |
if deliveredAwbStatusObj is not None:
|
| 447 |
statusTime = get_py_datetime(awbDetails['StatusDateTime'])
|
479 |
bookedTime = get_py_date(awbDetails['deliveryDate'])
|
| - |
|
480 |
delivered_orders[awb] = str(bookedTime) + "|" + "Not Available"
|
| - |
|
481 |
continue
|
| - |
|
482 |
|
| 448 |
#statusDate = awbDetails['StatusDateTime']
|
483 |
rtoAwbStatusObj = __get_scan_by_code(xmlScans, REASON_CODES_RTO)
|
| 449 |
#tracking = awbDetails['Tracking']
|
484 |
if rtoAwbStatusObj is not None:
|
| 450 |
if status.startswith("Delivered"):
|
485 |
bookedTime = rtoAwbStatusObj.statusDate
|
| 451 |
delivered_orders[awb] = str(statusTime) + "|" + "Not Available"
|
486 |
delivered_orders[awb] = str(bookedTime) + "|" + "Not Available"
|
| - |
|
487 |
continue
|
| - |
|
488 |
|
| 452 |
|
489 |
|
| - |
|
490 |
undeliveredAwbStatusObj = __get_scan_by_code(xmlScans, REASON_CODES_UNDELIVERED_MAP.keys())
|
| 453 |
if status.startswith('RTO'):
|
491 |
if undeliveredAwbStatusObj is not None:
|
| 454 |
returned_orders[awb] = str(statusTime) + "|" + "Not Available"
|
492 |
delivered_orders[awb] = REASON_CODES_UNDELIVERED_MAP.get(undeliveredAwbStatusObj.reasonCodeNumber)
|
| 455 |
|
493 |
|
| - |
|
494 |
|
| - |
|
495 |
|
| 456 |
undelivered_orders[awb] = status
|
496 |
#undelivered_orders[awb] = awbDetails.statusDescription
|
| 457 |
|
497 |
|
| 458 |
print "Delivered Orders:"
|
498 |
print "Delivered Orders:"
|
| 459 |
print delivered_orders
|
499 |
print delivered_orders
|
| 460 |
|
500 |
|
| 461 |
print "Returned Orders:"
|
501 |
print "Returned Orders:"
|
| Line 605... |
Line 645... |
| 605 |
|
645 |
|
| 606 |
def get_py_datetime(time_string):
|
646 |
def get_py_datetime(time_string):
|
| 607 |
# This should be a command line argument.
|
647 |
# This should be a command line argument.
|
| 608 |
# Refer http://docs.python.org/library/time.html#time.strftime to
|
648 |
# Refer http://docs.python.org/library/time.html#time.strftime to
|
| 609 |
# get a complete list of format specifiers available for date time.
|
649 |
# get a complete list of format specifiers available for date time.
|
| 610 |
time_format = "%d-%m-%Y %H:%M:%S"
|
650 |
time_format = "%d %b, %Y, %H:%M"
|
| - |
|
651 |
if time_string == '':
|
| - |
|
652 |
return None
|
| - |
|
653 |
return datetime.datetime.strptime(time_string, time_format)
|
| - |
|
654 |
|
| - |
|
655 |
def get_py_date(time_string):
|
| - |
|
656 |
# This should be a command line argument.
|
| - |
|
657 |
# Refer http://docs.python.org/library/time.html#time.strftime to
|
| - |
|
658 |
# get a complete list of format specifiers available for date time.
|
| - |
|
659 |
time_format = "%d-%b-%Y"
|
| 611 |
if time_string == '':
|
660 |
if time_string == '':
|
| 612 |
return None
|
661 |
return None
|
| 613 |
return datetime.datetime.strptime(time_string, time_format)
|
662 |
return datetime.datetime.strptime(time_string, time_format)
|
| 614 |
|
663 |
|
| 615 |
def getOriginCityBranchID(originCity):
|
664 |
def getOriginCityBranchID(originCity):
|
| Line 660... |
Line 709... |
| 660 |
#process_dao_pickup_orders(provider)
|
709 |
#process_dao_pickup_orders(provider)
|
| 661 |
#process_return_pickup_orders(provider)
|
710 |
#process_return_pickup_orders(provider)
|
| 662 |
if options.delivery_report:
|
711 |
if options.delivery_report:
|
| 663 |
#process_local_connection_orders(provider)
|
712 |
#process_local_connection_orders(provider)
|
| 664 |
#process_reached_destination_city_orders(provider)
|
713 |
#process_reached_destination_city_orders(provider)
|
| 665 |
process_first_delivery_attempt_orders(provider)
|
714 |
#process_first_delivery_attempt_orders(provider)
|
| 666 |
process_delivery_report(provider)
|
715 |
process_delivery_report(provider)
|
| 667 |
#create_crm_tickets_for_delivey_attempted_orders(provider)
|
716 |
#create_crm_tickets_for_delivey_attempted_orders(provider)
|
| 668 |
#auto_close_crm_tickets_created()
|
717 |
#auto_close_crm_tickets_created()
|
| 669 |
if options.gen_reports:
|
718 |
if options.gen_reports:
|
| 670 |
pass
|
719 |
pass
|
| 671 |
#generate_reports(provider)
|
720 |
#generate_reports(provider)
|
| 672 |
|
721 |
|
| 673 |
if __name__ == '__main__':
|
722 |
if __name__ == '__main__':
|
| 674 |
#main()
|
723 |
main()
|
| - |
|
724 |
#awbs =["897986473","225839621", "225839622", "225839623", "22583962"]
|
| 675 |
get_awb_status(["102019265","80005448"])
|
725 |
#for awb, awbDetails in get_awb_status(awbs).iteritems():
|
| - |
|
726 |
#print awb, awbDetails
|