Subversion Repositories SmartDukaan

Rev

Rev 9893 | Rev 13144 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6952 rajveer 1
#!/usr/bin/python
2
'''
3
It processes the following orders:
4
 1. Orders in DOA_PICKUP_CONFIRMED status : get details of orders that 
5
     were in DOA_PICKUP_CONFIRMED status from database and 
6
     calls BlueDart api to know whether they are picked up by BlueDart
7
     and changes the status to DOA_RETURN_IN_TRANSIT if it is done.
8
 2. Orders in RET_PICKUP_CONFIRMED status : get details of orders that 
9
     were in RET_PICKUP_CONFIRMED status from database and 
10
     calls BlueDart api to know whether they are picked up by BlueDart
11
     and changes the status to RET_RETURN_IN_TRANSIT if it is done.
12
 3. Orders in SHIPPED_FROM_WH status: get details of orders that
13
     were in SHIPPED_FROM_WH status from database and 
14
     calls BlueDart api to know whether they are picked up by BlueDart
15
     and changes the status to SHIPPED_TO_LOGST if it is done.
16
 4. Orders in SHIPPED_TO_LOGST status: get details of orders that
17
     were in SHIPPED_TO_LOGST status from database and 
18
     calls BlueDart api to know their status and changes the status accordingly.
19
 
20
It sends out a Pickup mismatch report, Return orders Pickup Mismatch report, Doa Pickup mismatch report,
21
Undelivered orders report and Returned Orders report to cnc.center@shop2020.in
22
 
23
http://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 coded
24
to track DOA orders and for other orders ConfigClient is called to get bluedart_update_url
25
 
26
@author: Phani Kumar
27
'''
13085 amit.gupta 28
from datetime import datetime
6952 rajveer 29
from shop2020.clients.CRMClient import CRMClient
30
from shop2020.clients.LogisticsClient import LogisticsClient
31
from shop2020.clients.TransactionClient import TransactionClient
13085 amit.gupta 32
from shop2020.model.v1.order.script.LogisticUtils import \
33
    create_crm_tickets_for_delivey_attempted_orders
34
from shop2020.thriftpy.crm.ttypes import TicketCategory, TicketPriority, \
35
    TicketStatus, Activity, ActivityType, SearchFilter
6952 rajveer 36
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \
37
    OrderStatus
38
from shop2020.utils.EmailAttachmentSender import get_attachment_part, mail
39
from shop2020.utils.Utils import to_py_date
13085 amit.gupta 40
from suds.client import Client
41
from xml.etree.ElementTree import parse, fromstring
42
import StringIO
43
import ast
6952 rajveer 44
import csv
13085 amit.gupta 45
import gzip
46
import json
6952 rajveer 47
import optparse
48
import sys
49
import time
50
import traceback
51
import urllib2
13085 amit.gupta 52
import xmltodict
8714 manish.sha 53
import zlib
6952 rajveer 54
if __name__ == '__main__' and __package__ is None:
55
    import os
56
    sys.path.insert(0, os.getcwd())
57
 
58
 
59
RED_EXPRESS_URL = "http://tracking.getsetred.net/TrackingService.svc?wsdl"
60
username = 'C00086721141'
9893 manish.sha 61
password = '87e95$'
8714 manish.sha 62
tracking_Id_Type = 'REFERENCENO'
63
tracking_Level = 'ALL_DETAILS'
6952 rajveer 64
 
8714 manish.sha 65
RED_EXPRESS_TRACKING_URL = 'http://webservices.getsetred.net/Services/BulkTracking.svc/'
66
headers = {
67
               "User-Agent" : "Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.218 Safari/535.1",
68
               "Accept" : "    text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8",
69
               "Accept-Language" : "en-us,en;q=0.5",
70
               "Accept-Encoding" : "gzip, deflate",
71
               "Connection" : "keep-alive",
72
               "Accept-Charset" : "ISO-8859-1",
73
               "Content-type": "application/json; charset=UTF-8"
74
               }
75
 
6952 rajveer 76
client = None
77
def getClient():
78
    global client
79
    if client is None:
80
        client = Client(RED_EXPRESS_URL, timeout=70)
81
    return client
82
 
8292 manish.sha 83
defaultUndeliveredAsssigneeId = 47
13085 amit.gupta 84
dtrUndeliveredAsssigneeId = 33
85
 
6952 rajveer 86
from_user = 'cnc.center@shop2020.in'
87
from_pwd = '5h0p2o2o'
9173 manish.sha 88
to = ['cnc.center@shop2020.in', "amit.sirohi@shop2020.in", "sandeep.sachdeva@shop2020.in", "sunil.kumar@shop2020.in", "rajveer.singh@shop2020.in"]
6952 rajveer 89
 
90
 
91
def get_updates(awb_number): 
13085 amit.gupta 92
    str1 = getClient().service.ProcessTrackingRequest('<TrackingRequest><Request><UserID>' + username + '</UserID><Password>' + password + '</Password><TrackingID>' + awb_number + '</TrackingID><TrackingLevel>ALL_DETAILS</TrackingLevel></Request></TrackingRequest>')
93
    return str1
6952 rajveer 94
 
7026 rajveer 95
def get_updates_for_user(awb_number):
96
    root =  fromstring(str(get_updates(awb_number)))
97
    children = root.getchildren()
98
    results = []
99
    for child in children:
100
        nodes = child.findall('ShipmentInfo/ShipmentEvent')
101
        for element in reversed(nodes):
102
            datestring = element.findtext('Date', '')
103
            timestring = element.findtext('Time', '')
104
            description = element.findtext('ServiceEvent', '')
105
            results.append(datestring+"~!~"+timestring+"~!~"+description)
106
    return results
6952 rajveer 107
 
8714 manish.sha 108
def get_track_updates(awb_numbers):
8838 manish.sha 109
    track_data_list=[]
110
    if len(awb_numbers)>0:
111
        req_args = json.dumps({'password':password,
112
                               'trackingIdType':'REFERENCENO',
113
                               'trackingLevel':'ALL_DETAILS',
114
                               'userId':username,
115
                               'waybillNo': awb_numbers 
116
                               })
117
        request = urllib2.Request(RED_EXPRESS_TRACKING_URL, req_args, headers)
118
        response = urllib2.urlopen(request)
8714 manish.sha 119
 
8838 manish.sha 120
        encoding = response.info().get("Content-Encoding")    
121
        if encoding in ('gzip', 'x-gzip', 'deflate'):
122
            content = response.read()
123
            if encoding == 'deflate':
124
                track_data_decoded = StringIO.StringIO(zlib.decompress(content))
125
            else:
126
                track_data_decoded = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(content))
127
        track_data_readable = track_data_decoded.read()
128
 
129
        conv_dict = xmltodict.parse(track_data_readable)
130
        track_data_json= json.dumps(conv_dict)
131
        if track_data_json.find('null') > 0:
132
            track_data_json = track_data_json.replace('null','\"No Description Available\"');
8714 manish.sha 133
        track_data_dict = ast.literal_eval(track_data_json)
134
 
8838 manish.sha 135
        if len(awb_numbers)==1:
136
            track_data_list=[]
137
            track_data_list.append(track_data_dict['BulkTrackingResponse']['BulkResponse']['TrackingResponse'])
138
            track_data_list.append('DUMMY')
139
        else:
140
            track_data_list = track_data_dict['BulkTrackingResponse']['BulkResponse']['TrackingResponse']    
141
 
8714 manish.sha 142
    return track_data_list
143
 
144
 
6952 rajveer 145
def process_dao_pickup_orders(provider):
146
    try:
147
        doas_tobe_picked_up = fetch_data(provider.id, [OrderStatus.DOA_PICKUP_CONFIRMED])
148
        doa_pickup_details = read_dao_return_pickup_orders(doas_tobe_picked_up)
149
        if doa_pickup_details:
150
            update_picked_doas(provider.id, doa_pickup_details)
151
    except:
152
        print "Some issue while processing the orders in DOA_PICKUP_CONFIRMED status"
153
        traceback.print_exc()
154
 
155
def process_return_pickup_orders(provider):
156
    try:
157
        returns_tobe_picked_up = fetch_data(provider.id, [OrderStatus.RET_PICKUP_CONFIRMED])
158
        returns_pickup_details = read_dao_return_pickup_orders(returns_tobe_picked_up)
159
        if returns_pickup_details:
160
            update_picked_returns(provider.id, returns_pickup_details)
161
    except:
162
        print "Some issue while processing the orders in RET_PICKUP_CONFIRMED status"
163
        traceback.print_exc()
164
 
165
def process_pickup_records(provider):
166
    try:
167
        orders_tobe_picked_up = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH])
168
        pickup_details = read_pickup_orders(orders_tobe_picked_up)
169
        if pickup_details:
170
            update_picked_orders(provider.id, pickup_details)
171
    except:
172
        print "Some issue while processing the orders in SHIPPED_FROM_WH status"
173
        traceback.print_exc()
174
 
175
def process_local_connection_orders(provider):
176
    try:
177
        orders_tobe_local_connected = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST])
178
        local_connected_orders = read_local_connection_orders(orders_tobe_local_connected)
179
        if local_connected_orders:
180
            update_local_connected_orders(provider.id, local_connected_orders)
181
    except:
182
        print "Some issue while processing the orders for local connection status"
183
        traceback.print_exc()
184
 
7025 rajveer 185
def process_first_delivery_attempt_orders(provider):
186
    try:
187
        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])
188
        first_atdl_orders = read_first_delivery_attempt_orders(orders_tobe_first_delivery_attempted)
189
        if first_atdl_orders:
190
            update_first_atdl_orders(provider.id, first_atdl_orders)
191
    except:
192
        print "Some issue while processing the orders for First delivery attempt status"
193
        traceback.print_exc()
194
 
6952 rajveer 195
def process_reached_destination_city_orders(provider):
196
    try:
197
        orders_tobe_reached_destination_city = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY])
198
        destination_city_reached_orders = read_reached_destination_orders(orders_tobe_reached_destination_city)
199
        if destination_city_reached_orders:
200
            update_destination_city_reached_orders(provider.id, destination_city_reached_orders)
201
    except:
202
        print "Some issue while processing the orders for Reached Destination City status"
203
        traceback.print_exc()
204
 
205
def process_delivery_report(provider):
206
    try:
207
        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])
208
        delivered_orders, returned_orders, undelivered_orders = read_delivery_orders(orders_tobe_delivered)
209
        if delivered_orders:
210
            update_delivered_orders(provider.id, delivered_orders)
211
        if returned_orders:
212
            update_returned_orders(provider.id, returned_orders)
213
        if undelivered_orders:
214
            update_reason_of_undelivered_orders(provider.id, undelivered_orders)
215
    except:
216
        print "Some issue while processing the orders for delivery status"
217
        traceback.print_exc()
218
 
219
def generate_reports(provider):
220
    get_doas_not_picked_up(provider)
221
    get_returns_not_picked_up(provider)
222
    get_orders_not_picked_up(provider)
223
    get_orders_pending_local_connection(provider)
224
    get_returned_orders(provider)
225
    get_orders_not_delivered(provider)
226
 
227
def get_doas_not_picked_up(provider):
228
    txnClient = TransactionClient().get_client()
229
    try:
230
        doas_not_picked_up = txnClient.getDoasNotPickedUp(provider.id)
231
    except TransactionServiceException as tex:
232
        print tex.message
233
 
234
    try:
235
        if doas_not_picked_up:
236
            print "DOAs not Picked up:"
237
            print doas_not_picked_up
238
            mismatch_file = "/tmp/BlueDart_DoaPickupMismatch.csv"
239
            print "Some of our DOA orders were not picked up. Printing report to:" + mismatch_file
240
            print_dao_return_pickup_mismatch_report(mismatch_file, doas_not_picked_up)
241
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
242
            mail(from_user, from_pwd, to,\
243
                 "DOA Pickup Mismatch for " + provider.name,\
244
                 "This is a system generated email.Please don't reply to it.",\
245
                 pickup_mismatch_part)
246
    except Exception:
247
        print "Some issue sending the DOA mismatch report"
248
        traceback.print_exc()
249
 
250
def get_returns_not_picked_up(provider):
251
    txnClient = TransactionClient().get_client()
252
    try:
253
        returns_not_picked_up = txnClient.getReturnOrdersNotPickedUp(provider.id)
254
    except TransactionServiceException as tex:
255
        print tex.message
256
 
257
    try:
258
        if returns_not_picked_up:
259
            print "Return Orders not Picked up:"
260
            print returns_not_picked_up
261
            mismatch_file = "/tmp/BlueDart_ReturnsPickupMismatch.csv"
262
            print "Some of our Return orders were not picked up. Printing report to:" + mismatch_file
263
            print_dao_return_pickup_mismatch_report(mismatch_file, returns_not_picked_up)
264
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
265
            mail(from_user, from_pwd, to,\
266
                 "Return orders Pickup Mismatch for " + provider.name,\
267
                 "This is a system generated email.Please don't reply to it.",\
268
                 pickup_mismatch_part)
269
    except Exception:
270
        print "Some issue sending the Return orders mismatch report"
271
        traceback.print_exc()
272
 
273
def get_orders_not_picked_up(provider):
274
    txnClient = TransactionClient().get_client()
275
    try:
276
        orders_not_picked_up = txnClient.getOrdersNotPickedUp(provider.id)
277
    except TransactionServiceException as tex:
278
        print tex.message
279
 
280
    try:
281
        if orders_not_picked_up:
282
            print "Orders not Picked up:"
283
            print orders_not_picked_up
8883 manish.sha 284
            mismatch_file = "/tmp/RedExpress_PickupMismatch.csv"
6952 rajveer 285
            print "Some of our orders were not picked up. Printing report to:" + mismatch_file
286
            print_pickup_mismatch_report(mismatch_file, orders_not_picked_up)
287
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
288
            mail(from_user, from_pwd, to,\
289
                 "Order Pickup Mismatch for " + provider.name,\
290
                 "This is a system generated email.Please don't reply to it.",\
291
                 pickup_mismatch_part)
292
    except Exception:
293
        print "Some issue sending the pickup mismatch report"
294
        traceback.print_exc()
295
 
296
def get_orders_pending_local_connection(provider):
297
    txnClient = TransactionClient().get_client()
298
    try:
299
        orders_pending_local_connection = txnClient.getOrdersNotLocalConnected(provider.id)
300
    except TransactionServiceException as tex:
301
        print tex.message
302
 
303
    try:
304
        if orders_pending_local_connection:
305
            print "Local Connection Pending Orders:"
306
            print orders_pending_local_connection
8883 manish.sha 307
            mismatch_file = "/tmp/RedExpress_LocalConnectionPendingOrders.csv"
6952 rajveer 308
            print "Some of our Orders were not Shipped to Destination yet. Printing report to:" + mismatch_file
309
            print_undelivered_orders_report(mismatch_file, orders_pending_local_connection)
310
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
311
            mail(from_user, from_pwd, to,\
312
                 "Orders that are not Shipped to Destination yet for " + provider.name,\
313
                 "This is a system generated email.Please don't reply to it.",\
314
                 pickup_mismatch_part)
315
    except Exception:
316
        print "Some issue updating and sending the Local Connection orders report"
317
        traceback.print_exc()
318
 
319
def get_returned_orders(provider):
320
    txnClient = TransactionClient().get_client()
321
    try:
322
        returned_orders = txnClient.getRTOrders(provider.id)
323
    except TransactionServiceException as tex:
324
        print tex.message
325
 
326
    try:
327
        if returned_orders:
328
            print "Returned Orders:"
329
            print returned_orders
8883 manish.sha 330
            returned_orders_file = "/tmp/RedExpress_ReturnedOrders.csv"
6952 rajveer 331
            print "Some of our Orders were returned by logistics provider. Printing report to:" + returned_orders_file
332
            print_rto_orders_report(returned_orders_file, returned_orders)
333
            returned_orders_report = [get_attachment_part(returned_orders_file)]
334
            mail(from_user, from_pwd, to,\
335
                 "Returned Orders Report for " + provider.name,\
336
                 "This is a system generated email.Please don't reply to it.",\
337
                 returned_orders_report)
338
    except:
339
        print "Some issue sending the returned orders report"
340
        traceback.print_exc()
341
 
342
def get_orders_not_delivered(provider):
343
    txnClient = TransactionClient().get_client()
344
    try:
345
        orders_not_delivered = txnClient.getNonDeliveredOrdersbyCourier(provider.id)
346
    except TransactionServiceException as tex:
347
        print tex.message
348
 
349
    try:
350
        if orders_not_delivered:
351
            print "Undelivered Orders:"
352
            print orders_not_delivered
8883 manish.sha 353
            mismatch_file = "/tmp/RedExpress_UndeliveredOrders.csv"
6952 rajveer 354
            print "Some of our Orders were not delivered. Printing report to:" + mismatch_file
355
            print_undelivered_orders_report(mismatch_file, orders_not_delivered)
356
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
357
            mail(from_user, from_pwd, to,\
358
                 "Orders that are undelivered but picked up or shipped four days ago for " + provider.name,\
359
                 "This is a system generated email.Please don't reply to it.",\
360
                 pickup_mismatch_part)
361
    except Exception:
362
        print "Some issue updating and sending the undelivered orders report"
363
        traceback.print_exc()
364
 
365
def get_provider_by_name(provider_name):
366
    logistics_client = LogisticsClient().get_client()
367
    provider = None
368
    providers = logistics_client.getAllProviders()
369
    for p in providers:
370
        if p.name == provider_name:
371
            provider=p
372
            break
373
    if provider == None:
374
        sys.exit("Can't continue execution: No such provider")
375
    return provider
376
 
377
def fetch_data(provider_id, order_status_list):
378
    txnClient = TransactionClient().get_client()
379
    try:
380
        doas_tobe_picked_up = txnClient.getOrdersForProviderForStatus(provider_id, order_status_list)
381
        return doas_tobe_picked_up
382
    except TransactionServiceException as tex:
383
        print tex.message
384
 
385
def read_dao_return_pickup_orders(orders_tobe_picked_up):
386
    #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=82390
387
    picked_up_orders = {}
388
    for order in orders_tobe_picked_up:
389
        try:
390
            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)
391
            root = parse(urllib2.urlopen(uri)).getroot()
392
            children = root.getchildren()
393
            for child in children:
394
                nodes = child.findall('Scans/ScanDetail')
395
                for element in reversed(nodes):
396
                    datestring = element.findtext('ScanDate', '')
397
                    timestring = element.findtext('ScanTime', '')
398
                    delivery_date = get_py_datetime(datestring, timestring)
399
                    picked_up_orders[order.pickupRequestNo] = str(delivery_date)
400
                    break
401
                break
402
        except:
403
            pass
404
 
405
    print "Picked up Orders:"
406
    print picked_up_orders
407
    return picked_up_orders
408
 
409
def read_pickup_orders(orders_tobe_picked_up):
410
    picked_up_orders = {}
8714 manish.sha 411
    awb_number_list =[]
6952 rajveer 412
    for order in orders_tobe_picked_up:
8714 manish.sha 413
        awb_number_list.append(order.airwaybill_no)
414
 
415
    track_update_list = get_track_updates(awb_number_list)
416
 
417
    for update in track_update_list:
418
        if update == 'DUMMY':
419
            continue
420
        else:
421
            try:
422
                airwaybill_no = update['ReferenceNo'] 
423
                track_list = update['TrackingList']['TrackingList']
8836 manish.sha 424
                #track_list.reverse()
8714 manish.sha 425
                for track_update in track_list:
426
                    if track_update['TrackingCode'] == 'BKD' :
8771 manish.sha 427
                        date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
8714 manish.sha 428
                        datestring  = date_obj.strftime("%Y-%m-%d")
429
                        timestring = track_update['ExecutionTime']+':00'
8772 manish.sha 430
                        delivery_date = datestring +' '+ timestring
8714 manish.sha 431
                        picked_up_orders[airwaybill_no] = delivery_date
432
                        break
433
            except:
434
                pass
435
 
6952 rajveer 436
    print "Picked up Orders:"
437
    print picked_up_orders
438
    return picked_up_orders
439
 
440
def read_local_connection_orders(orders_tobe_local_connected):
441
    local_connected_orders = {}
8714 manish.sha 442
 
443
    awb_number_list =[]
6952 rajveer 444
    for order in orders_tobe_local_connected:
8714 manish.sha 445
        awb_number_list.append(order.airwaybill_no)
446
 
447
    track_update_list = get_track_updates(awb_number_list)
448
 
449
    for update in track_update_list:
450
        if update == 'DUMMY':
451
            continue
452
        else:
453
            try:
454
                airwaybill_no = update['ReferenceNo'] 
455
                track_list = update['TrackingList']['TrackingList']
8836 manish.sha 456
                #track_list.reverse()
8714 manish.sha 457
                for track_update in track_list:
458
                    if track_update['TrackingCode'] == 'PRO' :
8771 manish.sha 459
                        date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
8714 manish.sha 460
                        datestring  = date_obj.strftime("%Y-%m-%d")
461
                        timestring = track_update['ExecutionTime']+':00'
8772 manish.sha 462
                        delivery_date = datestring +' '+ timestring
8714 manish.sha 463
                        local_connected_orders[airwaybill_no] = delivery_date
6952 rajveer 464
                        break
8714 manish.sha 465
            except:
466
                pass
7025 rajveer 467
 
6952 rajveer 468
    print "Local Connected Orders"
469
    print local_connected_orders
470
 
471
    return local_connected_orders
472
 
473
def read_reached_destination_orders(orders_tobe_reached_destination_city):
474
    destination_city_reached_orders = {}
8714 manish.sha 475
 
476
    awb_number_list =[]
6952 rajveer 477
    for order in orders_tobe_reached_destination_city:
8714 manish.sha 478
        awb_number_list.append(order.airwaybill_no)
479
 
480
    track_update_list = get_track_updates(awb_number_list)
481
 
482
    for update in track_update_list:
483
        if update == 'DUMMY':
484
            continue
485
        else:
486
            try:
487
                airwaybill_no = update['ReferenceNo'] 
488
                track_list = update['TrackingList']['TrackingList']
8836 manish.sha 489
                #track_list.reverse()
8714 manish.sha 490
                for track_update in track_list:
491
                    if track_update['TrackingCode'] == 'RDB' :
8771 manish.sha 492
                        date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
8714 manish.sha 493
                        datestring  = date_obj.strftime("%Y-%m-%d")
494
                        timestring = track_update['ExecutionTime']+':00'
8772 manish.sha 495
                        delivery_date = datestring +' '+ timestring
8714 manish.sha 496
                        destination_city_reached_orders[airwaybill_no] = delivery_date
6952 rajveer 497
                        break
8714 manish.sha 498
            except:
499
                pass
6952 rajveer 500
 
501
    print "Destination City Reached Orders"
502
    print destination_city_reached_orders
503
 
504
    return destination_city_reached_orders
505
 
506
def read_first_delivery_attempt_orders(orders_tobe_first_delivery_attempted):
507
    first_atdl_orders = {}
8714 manish.sha 508
 
509
    awb_number_list =[]
6952 rajveer 510
    for order in orders_tobe_first_delivery_attempted:
8714 manish.sha 511
        awb_number_list.append(order.airwaybill_no)
512
 
513
    track_update_list = get_track_updates(awb_number_list)
514
 
515
    for update in track_update_list:
516
        if update == 'DUMMY':
517
            continue
518
        else:
519
            try:
520
                airwaybill_no = update['ReferenceNo'] 
521
                track_list = update['TrackingList']['TrackingList']
8836 manish.sha 522
                #track_list.reverse()
8714 manish.sha 523
                for track_update in track_list:
524
                    if track_update['TrackingCode'] == 'OFD' :
8771 manish.sha 525
                        date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
8714 manish.sha 526
                        datestring  = date_obj.strftime("%Y-%m-%d")
527
                        timestring = track_update['ExecutionTime']+':00'
8772 manish.sha 528
                        delivery_date = datestring +' '+ timestring
8776 manish.sha 529
                        first_atdl_orders[airwaybill_no] = delivery_date +'|'+ track_update['ServiceEvent']
6952 rajveer 530
                        break
8714 manish.sha 531
            except:
532
                pass
533
 
6952 rajveer 534
 
535
    print "FIRST DELIVERY ATTEMPT MADE Orders"
536
    print first_atdl_orders
537
 
538
    return first_atdl_orders
539
 
540
def read_delivery_orders(orders_tobe_delivered):
541
    delivered_orders = {}
542
    returned_orders = {}
543
    undelivered_orders = {}
8714 manish.sha 544
    awb_order_map = {}
545
 
6952 rajveer 546
    for order in orders_tobe_delivered:
8714 manish.sha 547
        awb_order_list =[]
548
        awb_order_list.append(order.id)
549
        awb_order_list.append(order.shipping_timestamp)
550
        awb_order_map[order.airwaybill_no]= awb_order_list
6952 rajveer 551
 
8714 manish.sha 552
    track_update_list = get_track_updates(awb_order_map.keys())
553
 
554
    for update in track_update_list:
555
        if update == 'DUMMY':
556
            continue
557
        else:
558
            try:
559
                airwaybill_no = update['ReferenceNo'] 
560
                track_list = update['TrackingList']['TrackingList']
8836 manish.sha 561
                #track_list.reverse()
8714 manish.sha 562
                reason_for_return = None
563
                for record in track_list:
564
                    if record['TrackingCode'] == 'UDLD' :
565
                        reason_for_return = record['ServiceEvent'].split(" -")[1]
566
                        break
567
 
568
                for track_update in track_list:
569
                    if track_update['TrackingCode'] == 'DLVD' :
8771 manish.sha 570
                        date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
8714 manish.sha 571
                        datestring  = date_obj.strftime("%Y-%m-%d")
572
                        timestring = track_update['ExecutionTime']+':00'
8772 manish.sha 573
                        del_date = datestring +' '+ timestring
8771 manish.sha 574
                        delivery_date = datetime.datetime.strptime(del_date,"%Y-%m-%d %H:%M:%S")
8714 manish.sha 575
                        receiver = track_update['ServiceEvent'].split("[ ")[1].split(" ]")[0]
576
                        if to_py_date(awb_order_map.get(airwaybill_no)[1]) > delivery_date:
577
                            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))
578
                        else:
579
                            delivered_orders[airwaybill_no] = str(delivery_date) + "|" +  receiver
580
                        break
581
                    elif track_update['TrackingCode'] == 'RTO' :
8771 manish.sha 582
                        date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
8714 manish.sha 583
                        datestring  = date_obj.strftime("%Y-%m-%d")
584
                        timestring = track_update['ExecutionTime']+':00'
8772 manish.sha 585
                        del_date = datestring +' '+ timestring
8771 manish.sha 586
                        delivery_date = datetime.datetime.strptime(del_date,"%Y-%m-%d %H:%M:%S")
8714 manish.sha 587
                        if reason_for_return == None:
588
                            returned_orders[airwaybill_no] = str(delivery_date) + "|"  + " Order Booked for Return"
589
                        else:
590
                            returned_orders[airwaybill_no] = str(delivery_date) + "|"  + reason_for_return
591
                        break
592
                    elif track_update['TrackingCode'] == 'UDLD' :
8771 manish.sha 593
                        date_obj = datetime.datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
8714 manish.sha 594
                        datestring  = date_obj.strftime("%Y-%m-%d")
595
                        timestring = track_update['ExecutionTime']+':00'
8772 manish.sha 596
                        del_date = datestring +' '+ timestring
8771 manish.sha 597
                        delivery_date = datetime.datetime.strptime(del_date,"%Y-%m-%d %H:%M:%S")
8714 manish.sha 598
                        if reason_for_return == None:
599
                            undelivered_orders[airwaybill_no] = str(delivery_date) + "|" + track_update['ServiceEvent'].split(" -")[1]
600
                        else:
601
                            undelivered_orders[airwaybill_no] = str(delivery_date) + "|" + reason_for_return
602
                        break
603
            except:
604
                pass
605
 
6952 rajveer 606
    print "Delivered Orders:"
607
    print delivered_orders
608
 
609
    print "Returned Orders:"
610
    print returned_orders
611
 
612
    print "Undelivered Orders"
613
    print undelivered_orders
614
 
615
    return delivered_orders, returned_orders, undelivered_orders
616
 
617
def update_picked_orders(provider_id, pickup_details):
618
    txnClient = TransactionClient().get_client()
619
    try:
620
        txnClient.markOrdersAsPickedUp(provider_id, pickup_details)
621
    except TransactionServiceException as tex:
622
        print tex.message
623
 
624
def update_picked_doas(provider_id, doa_pickup_details):
625
    txnClient = TransactionClient().get_client()
626
    try:
627
        txnClient.markDoasAsPickedUp(provider_id, doa_pickup_details)
628
    except TransactionServiceException as tex:
629
        print tex.message
630
 
631
def update_picked_returns(provider_id, returns_pickup_details):
632
    txnClient = TransactionClient().get_client()
633
    try:
634
        txnClient.markReturnOrdersAsPickedUp(provider_id, returns_pickup_details)
635
    except TransactionServiceException as tex:
636
        print tex.message
637
 
638
def update_delivered_orders(provider_id, delivered_orders):
639
    txnClient = TransactionClient().get_client()
640
    try:
641
        txnClient.markOrdersAsDelivered(provider_id, delivered_orders)
642
    except TransactionServiceException as tex:
643
        print tex.message
644
 
645
def update_returned_orders(provider_id, returned_orders):
646
    txnClient = TransactionClient().get_client()
647
    try:
648
        txnClient.markAsRTOrders(provider_id, returned_orders)
649
    except TransactionServiceException as tex:
650
        print tex.message
651
 
652
def update_reason_of_undelivered_orders(provider_id, undelivered_orders):
653
    txnClient = TransactionClient().get_client()
654
    try:
655
        txnClient.updateNonDeliveryReason(provider_id, undelivered_orders)
656
    except TransactionServiceException as tex:
657
        print tex.message
658
 
659
def update_local_connected_orders(provider_id, local_connected_orders):
660
    txnClient = TransactionClient().get_client()
661
    try:
662
        txnClient.markOrdersAsLocalConnected(provider_id, local_connected_orders)
663
    except TransactionServiceException as tex:
664
        print tex.message
665
 
666
def update_destination_city_reached_orders(provider_id, destination_city_reached_orders):
667
    txnClient = TransactionClient().get_client()
668
    try:
669
        txnClient.markOrdersAsDestinationCityReached(provider_id, destination_city_reached_orders)
670
    except TransactionServiceException as tex:
671
        print tex.message
672
 
673
def update_first_atdl_orders(provider_id, first_atdl_orders):
674
    txnClient = TransactionClient().get_client()
675
    try:
676
        txnClient.markOrdersAsFirstDeliveryAttempted(provider_id, first_atdl_orders)
677
    except TransactionServiceException as tex:
678
        print tex.message
679
 
680
def print_pickup_mismatch_report(filename, orders):
681
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
682
    writer.writerow(['Order Id', 'AWB No', 'Shipping timestamp'])
683
    for order in orders:
684
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.shipping_timestamp)])
685
 
686
def print_dao_return_pickup_mismatch_report(filename, orders):
687
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
688
    writer.writerow(['Order Id', 'Pickup Request No', 'Authorization timestamp'])
689
    for order in orders:
690
        writer.writerow([order.id, order.pickupRequestNo, to_py_date(order.doa_auth_timestamp)])
691
 
692
def print_rto_orders_report(filename, orders):
693
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
694
    writer.writerow(['Order Id', 'AWB No', 'Return date', 'Reason'])
695
    for order in orders:
696
        statusDescription = ''
697
        if order.statusDescription is not None:
698
            statusDescription = order.statusDescription.replace(","," ")
699
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.delivery_timestamp), statusDescription])
700
 
701
def print_undelivered_orders_report(filename, orders):
702
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
703
    writer.writerow(['Order Id', 'AWB No', 'Status', 'Status Description', 'Shipping timestamp', 'Pickup timestamp', 'Promised delivery date', 'Expected delivery date', 'OTG'])
704
    for order in orders:
705
        statusDescription = ''
706
        if order.statusDescription is not None:
707
            statusDescription = order.statusDescription.replace(","," ")
708
        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'])
709
 
710
def auto_close_crm_tickets_created():
711
    try:
712
        ticket_created_orders = []
713
        tickets_map = {}
714
        crmServiceClient = CRMClient().get_client()
715
        searchFilter = SearchFilter()
716
        searchFilter.ticketCategory = TicketCategory.UNDELIVERED
717
        searchFilter.ticketAssigneeIds = [defaultUndeliveredAsssigneeId]
718
        searchFilter.ticketPriority = TicketPriority.HIGH
719
        searchFilter.ticketStatuses = [TicketStatus.OPEN]
720
        tickets = crmServiceClient.getTickets(searchFilter)
721
        print tickets
722
        for old_ticket in tickets:
723
            ticket_created_orders.append(old_ticket.orderId)
724
            tickets_map[old_ticket.orderId] = old_ticket
725
        print ticket_created_orders
726
        txnClient = TransactionClient().get_client()
727
        orders = txnClient.getOrderList(ticket_created_orders)
728
        for order in orders:
13085 amit.gupta 729
            if order.status not in [OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.RTO_IN_TRANSIT]:
6952 rajveer 730
                old_ticket = tickets_map.get(order.id)
731
                old_ticket.status = TicketStatus.CLOSED
732
                activity = Activity()
733
                activity.creatorId = 1
734
                activity.ticketAssigneeId = old_ticket.assigneeId
735
                activity.type = ActivityType.OTHER
736
                activity.description = "Ticket Closed bcoz order status changed to:" + order.statusDescription
737
                activity.ticketCategory = old_ticket.category
738
                activity.ticketDescription = old_ticket.description
739
                activity.ticketPriority = old_ticket.priority
740
                activity.ticketStatus = old_ticket.status
741
 
742
                if old_ticket.customerId is None or old_ticket.customerId == -1:
743
                    activity.customerEmailId = old_ticket.customerEmailId
744
                    activity.customerMobileNumber = old_ticket.customerMobileNumber
745
                    activity.customerName = old_ticket.customerName
746
                else:
747
                    activity.customerId = old_ticket.customerId
748
 
749
                crmServiceClient.updateTicket(old_ticket, activity)
750
    except:
751
        print "Some issue while closing crm tickets for orders in DELIVERY_SUCCESS status"
752
        traceback.print_exc()
753
 
754
def get_py_datetime(datestring, timestring):
755
    # This should be a command line argument.
756
    # Refer http://docs.python.org/library/time.html#time.strftime to
757
    # get a complete list of format specifiers available for date time.
758
    if datestring == '':
759
        return None
760
    if datestring.find('-') == -1:
761
        time_format = "%A,%d %B, %Y %H:%M:%S"
762
    else:
763
        time_format = "%d-%b-%Y %H:%M:%S"
764
    if timestring == '':
765
        timestring = '00:00:00'
766
    time_array = timestring.split(':')
767
    if len(time_array) < 3:
768
        timestring = timestring + ':00'
769
    time_string = datestring + ' ' + timestring[0:8]
770
    mytime = time.strptime(time_string, time_format)
771
    return datetime.datetime(*mytime[:6])
772
 
773
 
774
def getTrimedString(text):
775
    if text is None or text == '':
776
        return ''
777
    else:
778
        text = text.strip().lower()
779
        text_list = list(text)
780
        new_text = ''
781
        for letter in text_list:
782
            if letter.isalnum():
783
                new_text = new_text + str(letter)
784
        return new_text
785
 
786
def main():
787
    parser = optparse.OptionParser()
788
    parser.add_option("-p", "--pickup", dest="pickup_report",
789
                   action="store_true",
790
                   help="Run the pickup reconciliation")
791
    parser.add_option("-d", "--delivery", dest="delivery_report",
792
                   action="store_true",
793
                   help="Run the delivery reconciliation")
794
    parser.add_option("-r", "--reports", dest="gen_reports",
795
                   action="store_true",
796
                   help="Generate logistic reconciliation reports")
797
    parser.add_option("-a", "--all", dest="all_reports",
798
                   action="store_true",
799
                   help="Run all reconciliations")
800
    parser.add_option("-P", "--provider", dest="provider",
6966 rajveer 801
                   default="RedExpress", type="string",
6952 rajveer 802
                   help="The PROVIDER this report is for",
803
                   metavar="PROVIDER")
804
    parser.set_defaults(pickup_report=False, delivery_report=False, gen_reports=False, all_reports=False)
805
    (options, args) = parser.parse_args()
806
    if len(args) != 0:
807
        parser.error("You've supplied extra arguments. Are you sure you want to run this program?")
808
 
809
    if options.all_reports:
810
        options.pickup_report = True
811
        options.delivery_report = True
812
 
813
    provider = get_provider_by_name(options.provider)
814
 
815
    if options.pickup_report:
816
        process_pickup_records(provider)
817
        #process_dao_pickup_orders(provider)
818
        #process_return_pickup_orders(provider)
819
    if options.delivery_report:
820
        process_local_connection_orders(provider)
7025 rajveer 821
        process_reached_destination_city_orders(provider)
822
        process_first_delivery_attempt_orders(provider)
6952 rajveer 823
        process_delivery_report(provider)
7025 rajveer 824
        create_crm_tickets_for_delivey_attempted_orders(provider)
825
        auto_close_crm_tickets_created()
6952 rajveer 826
    if options.gen_reports:
827
        generate_reports(provider)
828
 
829
if __name__ == '__main__':
830
    main()