Rev 13144 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#!/usr/bin/python'''It processes the following orders:1. Orders in DOA_PICKUP_CONFIRMED status : get details of orders thatwere in DOA_PICKUP_CONFIRMED status from database andcalls BlueDart api to know whether they are picked up by BlueDartand changes the status to DOA_RETURN_IN_TRANSIT if it is done.2. Orders in RET_PICKUP_CONFIRMED status : get details of orders thatwere in RET_PICKUP_CONFIRMED status from database andcalls BlueDart api to know whether they are picked up by BlueDartand changes the status to RET_RETURN_IN_TRANSIT if it is done.3. Orders in SHIPPED_FROM_WH status: get details of orders thatwere in SHIPPED_FROM_WH status from database andcalls BlueDart api to know whether they are picked up by BlueDartand changes the status to SHIPPED_TO_LOGST if it is done.4. Orders in SHIPPED_TO_LOGST status: get details of orders thatwere in SHIPPED_TO_LOGST status from database andcalls BlueDart api to know their status and changes the status accordingly.It sends out a Pickup mismatch report, Return orders Pickup Mismatch report, Doa Pickup mismatch report,Undelivered orders report and Returned Orders report to cnc.center@shop2020.inhttp://www.bluedart.com/servlet/RoutingServlet?handler=tnt&action=custawbquery&loginid=DEL24119&awb=ref&format=XML&lickey=6265d61bafa6292c5ddfdb1ee335ca80&verno=1.3&scan=1&numbers={variable1} is hard codedto track DOA orders and for other orders ConfigClient is called to get bluedart_update_url@author: Phani Kumar'''from datetime import datetimefrom shop2020.clients.CRMClient import CRMClientfrom shop2020.clients.LogisticsClient import LogisticsClientfrom shop2020.clients.TransactionClient import TransactionClientfrom shop2020.model.v1.order.script.LogisticUtils import \create_crm_tickets_for_delivey_attempted_ordersfrom shop2020.thriftpy.crm.ttypes import TicketCategory, TicketPriority, \TicketStatus, Activity, ActivityType, SearchFilterfrom shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \OrderStatusfrom shop2020.utils.EmailAttachmentSender import get_attachment_part, mailfrom shop2020.utils.Utils import to_py_datefrom suds.client import Clientfrom xml.etree.ElementTree import parse, fromstringimport StringIOimport astimport csvimport gzipimport jsonimport optparseimport sysimport timeimport tracebackimport urllib2import xmltodictimport zlibimport datetimeif __name__ == '__main__' and __package__ is None:import ossys.path.insert(0, os.getcwd())RED_EXPRESS_URL = "http://tracking.getsetred.net/TrackingService.svc?wsdl"username = 'C00086721141'password = '87e95$'tracking_Id_Type = 'REFERENCENO'tracking_Level = 'ALL_DETAILS'RED_EXPRESS_TRACKING_URL = 'http://webservices.getsetred.net/Services/BulkTracking.svc/'headers = {"User-Agent" : "Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.218 Safari/535.1","Accept" : " text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8","Accept-Language" : "en-us,en;q=0.5","Accept-Encoding" : "gzip, deflate","Connection" : "keep-alive","Accept-Charset" : "ISO-8859-1","Content-type": "application/json; charset=UTF-8"}client = Nonedef getClient():global clientif client is None:client = Client(RED_EXPRESS_URL, timeout=70)return clientdefaultUndeliveredAsssigneeId = 65dtrUndeliveredAsssigneeId = 33from_user = 'cnc.center@shop2020.in'from_pwd = '5h0p2o2o'to = ['cnc.center@shop2020.in', "amit.sirohi@shop2020.in", "sandeep.sachdeva@shop2020.in", "sunil.kumar@shop2020.in", "rajveer.singh@shop2020.in"]def get_updates(awb_number):str1 = getClient().service.ProcessTrackingRequest('<TrackingRequest><Request><UserID>' + username + '</UserID><Password>' + password + '</Password><TrackingID>' + awb_number + '</TrackingID><TrackingLevel>ALL_DETAILS</TrackingLevel></Request></TrackingRequest>')return str1def get_updates_for_user(awb_number):root = fromstring(str(get_updates(awb_number)))children = root.getchildren()results = []for child in children:nodes = child.findall('ShipmentInfo/ShipmentEvent')for element in reversed(nodes):datestring = element.findtext('Date', '')timestring = element.findtext('Time', '')description = element.findtext('ServiceEvent', '')results.append(datestring+"~!~"+timestring+"~!~"+description)return resultsdef get_track_updates(awb_numbers):track_data_list=[]if len(awb_numbers)>0:req_args = json.dumps({'password':password,'trackingIdType':'REFERENCENO','trackingLevel':'ALL_DETAILS','userId':username,'waybillNo': awb_numbers})request = urllib2.Request(RED_EXPRESS_TRACKING_URL, req_args, headers)response = urllib2.urlopen(request)encoding = response.info().get("Content-Encoding")if encoding in ('gzip', 'x-gzip', 'deflate'):content = response.read()if encoding == 'deflate':track_data_decoded = StringIO.StringIO(zlib.decompress(content))else:track_data_decoded = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(content))track_data_readable = track_data_decoded.read()conv_dict = xmltodict.parse(track_data_readable)track_data_json= json.dumps(conv_dict)if track_data_json.find('null') > 0:track_data_json = track_data_json.replace('null','\"No Description Available\"');track_data_dict = ast.literal_eval(track_data_json)if len(awb_numbers)==1:track_data_list=[]track_data_list.append(track_data_dict['BulkTrackingResponse']['BulkResponse']['TrackingResponse'])track_data_list.append('DUMMY')else:track_data_list = track_data_dict['BulkTrackingResponse']['BulkResponse']['TrackingResponse']return track_data_listdef process_dao_pickup_orders(provider):try:doas_tobe_picked_up = fetch_data(provider.id, [OrderStatus.DOA_PICKUP_CONFIRMED])doa_pickup_details = read_dao_return_pickup_orders(doas_tobe_picked_up)if doa_pickup_details:update_picked_doas(provider.id, doa_pickup_details)except:print "Some issue while processing the orders in DOA_PICKUP_CONFIRMED status"traceback.print_exc()def process_return_pickup_orders(provider):try:returns_tobe_picked_up = fetch_data(provider.id, [OrderStatus.RET_PICKUP_CONFIRMED])returns_pickup_details = read_dao_return_pickup_orders(returns_tobe_picked_up)if returns_pickup_details:update_picked_returns(provider.id, returns_pickup_details)except:print "Some issue while processing the orders in RET_PICKUP_CONFIRMED status"traceback.print_exc()def process_pickup_records(provider):try:orders_tobe_picked_up = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH])pickup_details = read_pickup_orders(orders_tobe_picked_up)if pickup_details:update_picked_orders(provider.id, pickup_details)except:print "Some issue while processing the orders in SHIPPED_FROM_WH status"traceback.print_exc()def process_local_connection_orders(provider):try:orders_tobe_local_connected = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST])local_connected_orders = read_local_connection_orders(orders_tobe_local_connected)if local_connected_orders:update_local_connected_orders(provider.id, local_connected_orders)except:print "Some issue while processing the orders for local connection status"traceback.print_exc()def process_first_delivery_attempt_orders(provider):try:orders_tobe_first_delivery_attempted = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY])first_atdl_orders = read_first_delivery_attempt_orders(orders_tobe_first_delivery_attempted)if first_atdl_orders:update_first_atdl_orders(provider.id, first_atdl_orders)except:print "Some issue while processing the orders for First delivery attempt status"traceback.print_exc()def process_reached_destination_city_orders(provider):try:orders_tobe_reached_destination_city = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY])destination_city_reached_orders = read_reached_destination_orders(orders_tobe_reached_destination_city)if destination_city_reached_orders:update_destination_city_reached_orders(provider.id, destination_city_reached_orders)except:print "Some issue while processing the orders for Reached Destination City status"traceback.print_exc()def process_delivery_report(provider):try: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])delivered_orders, returned_orders, undelivered_orders = read_delivery_orders(orders_tobe_delivered)if delivered_orders:update_delivered_orders(provider.id, delivered_orders)if returned_orders:update_returned_orders(provider.id, returned_orders)if undelivered_orders:update_reason_of_undelivered_orders(provider.id, undelivered_orders)except:print "Some issue while processing the orders for delivery status"traceback.print_exc()def generate_reports(provider):get_doas_not_picked_up(provider)get_returns_not_picked_up(provider)get_orders_not_picked_up(provider)get_orders_pending_local_connection(provider)get_returned_orders(provider)get_orders_not_delivered(provider)def get_doas_not_picked_up(provider):txnClient = TransactionClient().get_client()try:doas_not_picked_up = txnClient.getDoasNotPickedUp(provider.id)except TransactionServiceException as tex:print tex.messagetry:if doas_not_picked_up:print "DOAs not Picked up:"print doas_not_picked_upmismatch_file = "/tmp/BlueDart_DoaPickupMismatch.csv"print "Some of our DOA orders were not picked up. Printing report to:" + mismatch_fileprint_dao_return_pickup_mismatch_report(mismatch_file, doas_not_picked_up)pickup_mismatch_part = [get_attachment_part(mismatch_file)]mail(from_user, from_pwd, to,\"DOA Pickup Mismatch for " + provider.name,\"This is a system generated email.Please don't reply to it.",\pickup_mismatch_part)except Exception:print "Some issue sending the DOA mismatch report"traceback.print_exc()def get_returns_not_picked_up(provider):txnClient = TransactionClient().get_client()try:returns_not_picked_up = txnClient.getReturnOrdersNotPickedUp(provider.id)except TransactionServiceException as tex:print tex.messagetry:if returns_not_picked_up:print "Return Orders not Picked up:"print returns_not_picked_upmismatch_file = "/tmp/BlueDart_ReturnsPickupMismatch.csv"print "Some of our Return orders were not picked up. Printing report to:" + mismatch_fileprint_dao_return_pickup_mismatch_report(mismatch_file, returns_not_picked_up)pickup_mismatch_part = [get_attachment_part(mismatch_file)]mail(from_user, from_pwd, to,\"Return orders Pickup Mismatch for " + provider.name,\"This is a system generated email.Please don't reply to it.",\pickup_mismatch_part)except Exception:print "Some issue sending the Return orders mismatch report"traceback.print_exc()def get_orders_not_picked_up(provider):txnClient = TransactionClient().get_client()try:orders_not_picked_up = txnClient.getOrdersNotPickedUp(provider.id)except TransactionServiceException as tex:print tex.messagetry:if orders_not_picked_up:print "Orders not Picked up:"print orders_not_picked_upmismatch_file = "/tmp/RedExpress_PickupMismatch.csv"print "Some of our orders were not picked up. Printing report to:" + mismatch_fileprint_pickup_mismatch_report(mismatch_file, orders_not_picked_up)pickup_mismatch_part = [get_attachment_part(mismatch_file)]mail(from_user, from_pwd, to,\"Order Pickup Mismatch for " + provider.name,\"This is a system generated email.Please don't reply to it.",\pickup_mismatch_part)except Exception:print "Some issue sending the pickup mismatch report"traceback.print_exc()def get_orders_pending_local_connection(provider):txnClient = TransactionClient().get_client()try:orders_pending_local_connection = txnClient.getOrdersNotLocalConnected(provider.id)except TransactionServiceException as tex:print tex.messagetry:if orders_pending_local_connection:print "Local Connection Pending Orders:"print orders_pending_local_connectionmismatch_file = "/tmp/RedExpress_LocalConnectionPendingOrders.csv"print "Some of our Orders were not Shipped to Destination yet. Printing report to:" + mismatch_fileprint_undelivered_orders_report(mismatch_file, orders_pending_local_connection)pickup_mismatch_part = [get_attachment_part(mismatch_file)]mail(from_user, from_pwd, to,\"Orders that are not Shipped to Destination yet for " + provider.name,\"This is a system generated email.Please don't reply to it.",\pickup_mismatch_part)except Exception:print "Some issue updating and sending the Local Connection orders report"traceback.print_exc()def get_returned_orders(provider):txnClient = TransactionClient().get_client()try:returned_orders = txnClient.getRTOrders(provider.id)except TransactionServiceException as tex:print tex.messagetry:if returned_orders:print "Returned Orders:"print returned_ordersreturned_orders_file = "/tmp/RedExpress_ReturnedOrders.csv"print "Some of our Orders were returned by logistics provider. Printing report to:" + returned_orders_fileprint_rto_orders_report(returned_orders_file, returned_orders)returned_orders_report = [get_attachment_part(returned_orders_file)]mail(from_user, from_pwd, to,\"Returned Orders Report for " + provider.name,\"This is a system generated email.Please don't reply to it.",\returned_orders_report)except:print "Some issue sending the returned orders report"traceback.print_exc()def get_orders_not_delivered(provider):txnClient = TransactionClient().get_client()try:orders_not_delivered = txnClient.getNonDeliveredOrdersbyCourier(provider.id)except TransactionServiceException as tex:print tex.messagetry:if orders_not_delivered:print "Undelivered Orders:"print orders_not_deliveredmismatch_file = "/tmp/RedExpress_UndeliveredOrders.csv"print "Some of our Orders were not delivered. Printing report to:" + mismatch_fileprint_undelivered_orders_report(mismatch_file, orders_not_delivered)pickup_mismatch_part = [get_attachment_part(mismatch_file)]mail(from_user, from_pwd, to,\"Orders that are undelivered but picked up or shipped four days ago for " + provider.name,\"This is a system generated email.Please don't reply to it.",\pickup_mismatch_part)except Exception:print "Some issue updating and sending the undelivered orders report"traceback.print_exc()def get_provider_by_name(provider_name):logistics_client = LogisticsClient().get_client()provider = Noneproviders = logistics_client.getAllProviders()for p in providers:if p.name == provider_name:provider=pbreakif provider == None:sys.exit("Can't continue execution: No such provider")return providerdef fetch_data(provider_id, order_status_list):txnClient = TransactionClient().get_client()try:doas_tobe_picked_up = txnClient.getOrdersForProviderForStatus(provider_id, order_status_list)return doas_tobe_picked_upexcept TransactionServiceException as tex:print tex.messagedef read_dao_return_pickup_orders(orders_tobe_picked_up):#uri=http://www.bluedart.com/servlet/RoutingServlet?handler=tnt&action=custawbquery&loginid=DEL24119&awb=ref&format=XML&lickey=6265d61bafa6292c5ddfdb1ee335ca80&verno=1.3&scan=1&numbers=82390picked_up_orders = {}for order in orders_tobe_picked_up:try:uri = 'http://www.bluedart.com/servlet/RoutingServlet?handler=tnt&action=custawbquery&loginid=DEL24119&awb=ref&format=XML&lickey=6265d61bafa6292c5ddfdb1ee335ca80&verno=1.3&scan=1&numbers=' + str(order.pickupRequestNo)root = parse(urllib2.urlopen(uri)).getroot()children = root.getchildren()for child in children:nodes = child.findall('Scans/ScanDetail')for element in reversed(nodes):datestring = element.findtext('ScanDate', '')timestring = element.findtext('ScanTime', '')delivery_date = get_py_datetime(datestring, timestring)picked_up_orders[order.pickupRequestNo] = str(delivery_date)breakbreakexcept:passprint "Picked up Orders:"print picked_up_ordersreturn picked_up_ordersdef read_pickup_orders(orders_tobe_picked_up):picked_up_orders = {}awb_number_list =[]for order in orders_tobe_picked_up:awb_number_list.append(order.airwaybill_no)track_update_list = get_track_updates(awb_number_list)for update in track_update_list:if update == 'DUMMY':continueelse:try:airwaybill_no = update['ReferenceNo']track_list = update['TrackingList']['TrackingList']#track_list.reverse()for track_update in track_list:if track_update['TrackingCode'] == 'BKD' :date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")datestring = date_obj.strftime("%Y-%m-%d")timestring = track_update['ExecutionTime']+':00'delivery_date = datestring +' '+ timestringpicked_up_orders[airwaybill_no] = delivery_datebreakexcept:passprint "Picked up Orders:"print picked_up_ordersreturn picked_up_ordersdef read_local_connection_orders(orders_tobe_local_connected):local_connected_orders = {}awb_number_list =[]for order in orders_tobe_local_connected:awb_number_list.append(order.airwaybill_no)track_update_list = get_track_updates(awb_number_list)for update in track_update_list:if update == 'DUMMY':continueelse:try:airwaybill_no = update['ReferenceNo']track_list = update['TrackingList']['TrackingList']#track_list.reverse()for track_update in track_list:if track_update['TrackingCode'] == 'PRO' :date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")datestring = date_obj.strftime("%Y-%m-%d")timestring = track_update['ExecutionTime']+':00'delivery_date = datestring +' '+ timestringlocal_connected_orders[airwaybill_no] = delivery_datebreakexcept:passprint "Local Connected Orders"print local_connected_ordersreturn local_connected_ordersdef read_reached_destination_orders(orders_tobe_reached_destination_city):destination_city_reached_orders = {}awb_number_list =[]for order in orders_tobe_reached_destination_city:awb_number_list.append(order.airwaybill_no)track_update_list = get_track_updates(awb_number_list)for update in track_update_list:if update == 'DUMMY':continueelse:try:airwaybill_no = update['ReferenceNo']track_list = update['TrackingList']['TrackingList']#track_list.reverse()for track_update in track_list:if track_update['TrackingCode'] == 'RDB' :date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")datestring = date_obj.strftime("%Y-%m-%d")timestring = track_update['ExecutionTime']+':00'delivery_date = datestring +' '+ timestringdestination_city_reached_orders[airwaybill_no] = delivery_datebreakexcept:passprint "Destination City Reached Orders"print destination_city_reached_ordersreturn destination_city_reached_ordersdef read_first_delivery_attempt_orders(orders_tobe_first_delivery_attempted):first_atdl_orders = {}awb_number_list =[]for order in orders_tobe_first_delivery_attempted:awb_number_list.append(order.airwaybill_no)track_update_list = get_track_updates(awb_number_list)for update in track_update_list:if update == 'DUMMY':continueelse:try:airwaybill_no = update['ReferenceNo']track_list = update['TrackingList']['TrackingList']#track_list.reverse()for track_update in track_list:if track_update['TrackingCode'] == 'OFD' :date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")datestring = date_obj.strftime("%Y-%m-%d")timestring = track_update['ExecutionTime']+':00'delivery_date = datestring +' '+ timestringfirst_atdl_orders[airwaybill_no] = delivery_date +'|'+ track_update['ServiceEvent']breakexcept:passprint "FIRST DELIVERY ATTEMPT MADE Orders"print first_atdl_ordersreturn first_atdl_ordersdef read_delivery_orders(orders_tobe_delivered):delivered_orders = {}returned_orders = {}undelivered_orders = {}awb_order_map = {}for order in orders_tobe_delivered:awb_order_list =[]awb_order_list.append(order.id)awb_order_list.append(order.shipping_timestamp)awb_order_map[order.airwaybill_no]= awb_order_listtrack_update_list = get_track_updates(awb_order_map.keys())for update in track_update_list:if update == 'DUMMY':continueelse:try:airwaybill_no = update['ReferenceNo']track_list = update['TrackingList']['TrackingList']#track_list.reverse()reason_for_return = Nonefor record in track_list:if record['TrackingCode'] == 'UDLD' :reason_for_return = record['ServiceEvent'].split(" -")[1]breakfor track_update in track_list:if track_update['TrackingCode'] == 'DLVD' :date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")datestring = date_obj.strftime("%Y-%m-%d")timestring = track_update['ExecutionTime']+':00'del_date = datestring +' '+ timestringdelivery_date = datetime.datetime.strptime(del_date,"%Y-%m-%d %H:%M:%S")receiver = track_update['ServiceEvent'].split("[ ")[1].split(" ]")[0]if to_py_date(awb_order_map.get(airwaybill_no)[1]) > delivery_date:mail(from_user, from_pwd, to, "Delivery Problem for Red Express", "Order id " + str(awb_order_map.get(airwaybill_no)[0]) + " has shipping date " + str(awb_order_map.get(airwaybill_no)[1]) + " larger than delivery date " + str(delivery_date))else:delivered_orders[airwaybill_no] = str(delivery_date) + "|" + receiverbreakelif track_update['TrackingCode'] == 'RTO' :date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")datestring = date_obj.strftime("%Y-%m-%d")timestring = track_update['ExecutionTime']+':00'del_date = datestring +' '+ timestringdelivery_date = datetime.datetime.strptime(del_date,"%Y-%m-%d %H:%M:%S")if reason_for_return == None:returned_orders[airwaybill_no] = str(delivery_date) + "|" + " Order Booked for Return"else:returned_orders[airwaybill_no] = str(delivery_date) + "|" + reason_for_returnbreakelif track_update['TrackingCode'] == 'UDLD' :date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")datestring = date_obj.strftime("%Y-%m-%d")timestring = track_update['ExecutionTime']+':00'del_date = datestring +' '+ timestringdelivery_date = datetime.datetime.strptime(del_date,"%Y-%m-%d %H:%M:%S")if reason_for_return == None:undelivered_orders[airwaybill_no] = str(delivery_date) + "|" + track_update['ServiceEvent'].split(" -")[1]else:undelivered_orders[airwaybill_no] = str(delivery_date) + "|" + reason_for_returnbreakexcept:passprint "Delivered Orders:"print delivered_ordersprint "Returned Orders:"print returned_ordersprint "Undelivered Orders"print undelivered_ordersreturn delivered_orders, returned_orders, undelivered_ordersdef update_picked_orders(provider_id, pickup_details):txnClient = TransactionClient().get_client()try:txnClient.markOrdersAsPickedUp(provider_id, pickup_details)except TransactionServiceException as tex:print tex.messagedef update_picked_doas(provider_id, doa_pickup_details):txnClient = TransactionClient().get_client()try:txnClient.markDoasAsPickedUp(provider_id, doa_pickup_details)except TransactionServiceException as tex:print tex.messagedef update_picked_returns(provider_id, returns_pickup_details):txnClient = TransactionClient().get_client()try:txnClient.markReturnOrdersAsPickedUp(provider_id, returns_pickup_details)except TransactionServiceException as tex:print tex.messagedef update_delivered_orders(provider_id, delivered_orders):txnClient = TransactionClient().get_client()try:txnClient.markOrdersAsDelivered(provider_id, delivered_orders)except TransactionServiceException as tex:print tex.messagedef update_returned_orders(provider_id, returned_orders):txnClient = TransactionClient().get_client()try:txnClient.markAsRTOrders(provider_id, returned_orders)except TransactionServiceException as tex:print tex.messagedef update_reason_of_undelivered_orders(provider_id, undelivered_orders):txnClient = TransactionClient().get_client()try:txnClient.updateNonDeliveryReason(provider_id, undelivered_orders)except TransactionServiceException as tex:print tex.messagedef update_local_connected_orders(provider_id, local_connected_orders):txnClient = TransactionClient().get_client()try:txnClient.markOrdersAsLocalConnected(provider_id, local_connected_orders)except TransactionServiceException as tex:print tex.messagedef update_destination_city_reached_orders(provider_id, destination_city_reached_orders):txnClient = TransactionClient().get_client()try:txnClient.markOrdersAsDestinationCityReached(provider_id, destination_city_reached_orders)except TransactionServiceException as tex:print tex.messagedef update_first_atdl_orders(provider_id, first_atdl_orders):txnClient = TransactionClient().get_client()try:txnClient.markOrdersAsFirstDeliveryAttempted(provider_id, first_atdl_orders)except TransactionServiceException as tex:print tex.messagedef print_pickup_mismatch_report(filename, orders):writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)writer.writerow(['Order Id', 'AWB No', 'Shipping timestamp'])for order in orders:writer.writerow([order.id, order.airwaybill_no, to_py_date(order.shipping_timestamp)])def print_dao_return_pickup_mismatch_report(filename, orders):writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)writer.writerow(['Order Id', 'Pickup Request No', 'Authorization timestamp'])for order in orders:writer.writerow([order.id, order.pickupRequestNo, to_py_date(order.doa_auth_timestamp)])def print_rto_orders_report(filename, orders):writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)writer.writerow(['Order Id', 'AWB No', 'Return date', 'Reason'])for order in orders:statusDescription = ''if order.statusDescription is not None:statusDescription = order.statusDescription.replace(","," ")writer.writerow([order.id, order.airwaybill_no, to_py_date(order.delivery_timestamp), statusDescription])def print_undelivered_orders_report(filename, orders):writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)writer.writerow(['Order Id', 'AWB No', 'Status', 'Status Description', 'Shipping timestamp', 'Pickup timestamp', 'Promised delivery date', 'Expected delivery date', 'OTG'])for order in orders:statusDescription = ''if order.statusDescription is not None:statusDescription = order.statusDescription.replace(","," ")writer.writerow([order.id, order.airwaybill_no, order.status, statusDescription, to_py_date(order.shipping_timestamp), to_py_date(order.pickup_timestamp), to_py_date(order.promised_delivery_time), to_py_date(order.expected_delivery_time), 'True' if order.otg else 'False'])def auto_close_crm_tickets_created():try:ticket_created_orders = []tickets_map = {}crmServiceClient = CRMClient().get_client()searchFilter = SearchFilter()searchFilter.ticketCategory = TicketCategory.UNDELIVEREDsearchFilter.ticketAssigneeIds = [defaultUndeliveredAsssigneeId]searchFilter.ticketPriority = TicketPriority.HIGHsearchFilter.ticketStatuses = [TicketStatus.OPEN]tickets = crmServiceClient.getTickets(searchFilter)print ticketsfor old_ticket in tickets:ticket_created_orders.append(old_ticket.orderId)tickets_map[old_ticket.orderId] = old_ticketprint ticket_created_orderstxnClient = TransactionClient().get_client()orders = txnClient.getOrderList(ticket_created_orders)for order in orders:if order.status not in [OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.RTO_IN_TRANSIT]:old_ticket = tickets_map.get(order.id)old_ticket.status = TicketStatus.CLOSEDactivity = Activity()activity.creatorId = 1activity.ticketAssigneeId = old_ticket.assigneeIdactivity.type = ActivityType.OTHERactivity.description = "Ticket Closed bcoz order status changed to:" + order.statusDescriptionactivity.ticketCategory = old_ticket.categoryactivity.ticketDescription = old_ticket.descriptionactivity.ticketPriority = old_ticket.priorityactivity.ticketStatus = old_ticket.statusif old_ticket.customerId is None or old_ticket.customerId == -1:activity.customerEmailId = old_ticket.customerEmailIdactivity.customerMobileNumber = old_ticket.customerMobileNumberactivity.customerName = old_ticket.customerNameelse:activity.customerId = old_ticket.customerIdcrmServiceClient.updateTicket(old_ticket, activity)except:print "Some issue while closing crm tickets for orders in DELIVERY_SUCCESS status"traceback.print_exc()def get_py_datetime(datestring, timestring):# This should be a command line argument.# Refer http://docs.python.org/library/time.html#time.strftime to# get a complete list of format specifiers available for date time.if datestring == '':return Noneif datestring.find('-') == -1:time_format = "%A,%d %B, %Y %H:%M:%S"else:time_format = "%d-%b-%Y %H:%M:%S"if timestring == '':timestring = '00:00:00'time_array = timestring.split(':')if len(time_array) < 3:timestring = timestring + ':00'time_string = datestring + ' ' + timestring[0:8]mytime = time.strptime(time_string, time_format)return datetime.datetime(*mytime[:6])def getTrimedString(text):if text is None or text == '':return ''else:text = text.strip().lower()text_list = list(text)new_text = ''for letter in text_list:if letter.isalnum():new_text = new_text + str(letter)return new_textdef main():parser = optparse.OptionParser()parser.add_option("-p", "--pickup", dest="pickup_report",action="store_true",help="Run the pickup reconciliation")parser.add_option("-d", "--delivery", dest="delivery_report",action="store_true",help="Run the delivery reconciliation")parser.add_option("-r", "--reports", dest="gen_reports",action="store_true",help="Generate logistic reconciliation reports")parser.add_option("-a", "--all", dest="all_reports",action="store_true",help="Run all reconciliations")parser.add_option("-P", "--provider", dest="provider",default="RedExpress", type="string",help="The PROVIDER this report is for",metavar="PROVIDER")parser.set_defaults(pickup_report=False, delivery_report=False, gen_reports=False, all_reports=False)(options, args) = parser.parse_args()if len(args) != 0:parser.error("You've supplied extra arguments. Are you sure you want to run this program?")if options.all_reports:options.pickup_report = Trueoptions.delivery_report = Trueprovider = get_provider_by_name(options.provider)if options.pickup_report:process_pickup_records(provider)#process_dao_pickup_orders(provider)#process_return_pickup_orders(provider)if options.delivery_report:process_local_connection_orders(provider)process_reached_destination_city_orders(provider)process_first_delivery_attempt_orders(provider)process_delivery_report(provider)create_crm_tickets_for_delivey_attempted_orders(provider)auto_close_crm_tickets_created()if options.gen_reports:generate_reports(provider)if __name__ == '__main__':main()