Subversion Repositories SmartDukaan

Rev

Rev 8292 | Rev 8700 | 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
'''
28
from shop2020.clients.CRMClient import CRMClient
29
from shop2020.clients.LogisticsClient import LogisticsClient
30
from shop2020.clients.TransactionClient import TransactionClient
31
from shop2020.clients.UserClient import UserClient
32
from LogisticUtils import enqueueMailForFDA
33
from shop2020.thriftpy.crm.ttypes import *
34
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \
35
    OrderStatus
36
from shop2020.utils.EmailAttachmentSender import get_attachment_part, mail
37
from shop2020.utils.Utils import to_py_date
38
from xml.etree.ElementTree import parse, XML, fromstring
8699 manish.sha 39
from datetime import datetime
6952 rajveer 40
import csv
41
import datetime
42
import optparse
43
import sys
44
import time
45
import traceback
46
import urllib2
47
from suds.client import Client
8699 manish.sha 48
import json
49
import StringIO
50
import zlib
51
import gzip
52
import xmltodict
53
import ast
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'
61
password = 'SANDEEP.SACHDEVA@SHOP2020.IN'
8699 manish.sha 62
tracking_Id_Type = 'REFERENCENO'
63
tracking_Level = 'ALL_DETAILS'
6952 rajveer 64
 
8699 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
6952 rajveer 84
from_user = 'cnc.center@shop2020.in'
85
from_pwd = '5h0p2o2o'
86
to = ['cnc.center@shop2020.in', "amit.sirohi@shop2020.in", "sandeep.sachdeva@shop2020.in", "manoj.kumar@shop2020.in", "rajveer.singh@shop2020.in"]
87
 
88
 
89
def get_updates(awb_number): 
90
    str = getClient().service.ProcessTrackingRequest('<TrackingRequest><Request><UserID>' + username + '</UserID><Password>' + password + '</Password><TrackingID>' + awb_number + '</TrackingID><TrackingLevel>ALL_DETAILS</TrackingLevel></Request></TrackingRequest>')
91
    print str
92
    return str
93
 
7026 rajveer 94
def get_updates_for_user(awb_number):
95
    root =  fromstring(str(get_updates(awb_number)))
96
    children = root.getchildren()
97
    results = []
98
    for child in children:
99
        nodes = child.findall('ShipmentInfo/ShipmentEvent')
100
        for element in reversed(nodes):
101
            datestring = element.findtext('Date', '')
102
            timestring = element.findtext('Time', '')
103
            description = element.findtext('ServiceEvent', '')
104
            results.append(datestring+"~!~"+timestring+"~!~"+description)
105
    return results
6952 rajveer 106
 
8699 manish.sha 107
def get_track_updates(awb_numbers):
108
    req_args = json.dumps({'password':password,
109
                           'trackingIdType':'REFERENCENO',
110
                           'trackingLevel':'ALL_DETAILS',
111
                           'userId':username,
112
                           'waybillNo': awb_numbers 
113
                           })
114
    request = urllib2.Request(RED_EXPRESS_TRACKING_URL, req_args, headers)
115
    response = urllib2.urlopen(request)
116
 
117
    encoding = response.info().get("Content-Encoding")    
118
    if encoding in ('gzip', 'x-gzip', 'deflate'):
119
        content = response.read()
120
        if encoding == 'deflate':
121
            track_data_decoded = StringIO.StringIO(zlib.decompress(content))
122
        else:
123
            track_data_decoded = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(content))
124
    track_data_readable = track_data_decoded.read()
125
 
126
    conv_dict = xmltodict.parse(track_data_readable)
127
    track_data_json= json.dumps(conv_dict)
128
 
129
    track_data_dict = ast.literal_eval(track_data_json)
130
 
131
    if len(awb_numbers)==1:
132
        track_data_list=[]
133
        track_data_list.append(track_data_dict['BulkTrackingResponse']['BulkResponse']['TrackingResponse'])
134
        track_data_list.append('DUMMY')
135
    else:
136
        track_data_list = track_data_dict['BulkTrackingResponse']['BulkResponse']['TrackingResponse']    
137
 
138
    return track_data_list
139
 
140
 
6952 rajveer 141
def process_dao_pickup_orders(provider):
142
    try:
143
        doas_tobe_picked_up = fetch_data(provider.id, [OrderStatus.DOA_PICKUP_CONFIRMED])
144
        doa_pickup_details = read_dao_return_pickup_orders(doas_tobe_picked_up)
145
        if doa_pickup_details:
146
            update_picked_doas(provider.id, doa_pickup_details)
147
    except:
148
        print "Some issue while processing the orders in DOA_PICKUP_CONFIRMED status"
149
        traceback.print_exc()
150
 
151
def process_return_pickup_orders(provider):
152
    try:
153
        returns_tobe_picked_up = fetch_data(provider.id, [OrderStatus.RET_PICKUP_CONFIRMED])
154
        returns_pickup_details = read_dao_return_pickup_orders(returns_tobe_picked_up)
155
        if returns_pickup_details:
156
            update_picked_returns(provider.id, returns_pickup_details)
157
    except:
158
        print "Some issue while processing the orders in RET_PICKUP_CONFIRMED status"
159
        traceback.print_exc()
160
 
161
def process_pickup_records(provider):
162
    try:
163
        orders_tobe_picked_up = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH])
164
        pickup_details = read_pickup_orders(orders_tobe_picked_up)
165
        if pickup_details:
166
            update_picked_orders(provider.id, pickup_details)
167
    except:
168
        print "Some issue while processing the orders in SHIPPED_FROM_WH status"
169
        traceback.print_exc()
170
 
171
def process_local_connection_orders(provider):
172
    try:
173
        orders_tobe_local_connected = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST])
174
        local_connected_orders = read_local_connection_orders(orders_tobe_local_connected)
175
        if local_connected_orders:
176
            update_local_connected_orders(provider.id, local_connected_orders)
177
    except:
178
        print "Some issue while processing the orders for local connection status"
179
        traceback.print_exc()
180
 
7025 rajveer 181
def process_first_delivery_attempt_orders(provider):
182
    try:
183
        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])
184
        first_atdl_orders = read_first_delivery_attempt_orders(orders_tobe_first_delivery_attempted)
185
        if first_atdl_orders:
186
            update_first_atdl_orders(provider.id, first_atdl_orders)
187
    except:
188
        print "Some issue while processing the orders for First delivery attempt status"
189
        traceback.print_exc()
190
 
6952 rajveer 191
def process_reached_destination_city_orders(provider):
192
    try:
193
        orders_tobe_reached_destination_city = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY])
194
        destination_city_reached_orders = read_reached_destination_orders(orders_tobe_reached_destination_city)
195
        if destination_city_reached_orders:
196
            update_destination_city_reached_orders(provider.id, destination_city_reached_orders)
197
    except:
198
        print "Some issue while processing the orders for Reached Destination City status"
199
        traceback.print_exc()
200
 
201
def process_delivery_report(provider):
202
    try:
203
        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])
204
        delivered_orders, returned_orders, undelivered_orders = read_delivery_orders(orders_tobe_delivered)
205
        if delivered_orders:
206
            update_delivered_orders(provider.id, delivered_orders)
207
        if returned_orders:
208
            update_returned_orders(provider.id, returned_orders)
209
        if undelivered_orders:
210
            update_reason_of_undelivered_orders(provider.id, undelivered_orders)
211
    except:
212
        print "Some issue while processing the orders for delivery status"
213
        traceback.print_exc()
214
 
215
def generate_reports(provider):
216
    get_doas_not_picked_up(provider)
217
    get_returns_not_picked_up(provider)
218
    get_orders_not_picked_up(provider)
219
    get_orders_pending_local_connection(provider)
220
    get_returned_orders(provider)
221
    get_orders_not_delivered(provider)
222
 
223
def get_doas_not_picked_up(provider):
224
    txnClient = TransactionClient().get_client()
225
    try:
226
        doas_not_picked_up = txnClient.getDoasNotPickedUp(provider.id)
227
    except TransactionServiceException as tex:
228
        print tex.message
229
 
230
    try:
231
        if doas_not_picked_up:
232
            print "DOAs not Picked up:"
233
            print doas_not_picked_up
234
            mismatch_file = "/tmp/BlueDart_DoaPickupMismatch.csv"
235
            print "Some of our DOA orders were not picked up. Printing report to:" + mismatch_file
236
            print_dao_return_pickup_mismatch_report(mismatch_file, doas_not_picked_up)
237
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
238
            mail(from_user, from_pwd, to,\
239
                 "DOA Pickup Mismatch for " + provider.name,\
240
                 "This is a system generated email.Please don't reply to it.",\
241
                 pickup_mismatch_part)
242
    except Exception:
243
        print "Some issue sending the DOA mismatch report"
244
        traceback.print_exc()
245
 
246
def get_returns_not_picked_up(provider):
247
    txnClient = TransactionClient().get_client()
248
    try:
249
        returns_not_picked_up = txnClient.getReturnOrdersNotPickedUp(provider.id)
250
    except TransactionServiceException as tex:
251
        print tex.message
252
 
253
    try:
254
        if returns_not_picked_up:
255
            print "Return Orders not Picked up:"
256
            print returns_not_picked_up
257
            mismatch_file = "/tmp/BlueDart_ReturnsPickupMismatch.csv"
258
            print "Some of our Return orders were not picked up. Printing report to:" + mismatch_file
259
            print_dao_return_pickup_mismatch_report(mismatch_file, returns_not_picked_up)
260
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
261
            mail(from_user, from_pwd, to,\
262
                 "Return orders Pickup Mismatch for " + provider.name,\
263
                 "This is a system generated email.Please don't reply to it.",\
264
                 pickup_mismatch_part)
265
    except Exception:
266
        print "Some issue sending the Return orders mismatch report"
267
        traceback.print_exc()
268
 
269
def get_orders_not_picked_up(provider):
270
    txnClient = TransactionClient().get_client()
271
    try:
272
        orders_not_picked_up = txnClient.getOrdersNotPickedUp(provider.id)
273
    except TransactionServiceException as tex:
274
        print tex.message
275
 
276
    try:
277
        if orders_not_picked_up:
278
            print "Orders not Picked up:"
279
            print orders_not_picked_up
280
            mismatch_file = "/tmp/BlueDart_PickupMismatch.csv"
281
            print "Some of our orders were not picked up. Printing report to:" + mismatch_file
282
            print_pickup_mismatch_report(mismatch_file, orders_not_picked_up)
283
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
284
            mail(from_user, from_pwd, to,\
285
                 "Order Pickup Mismatch for " + provider.name,\
286
                 "This is a system generated email.Please don't reply to it.",\
287
                 pickup_mismatch_part)
288
    except Exception:
289
        print "Some issue sending the pickup mismatch report"
290
        traceback.print_exc()
291
 
292
def get_orders_pending_local_connection(provider):
293
    txnClient = TransactionClient().get_client()
294
    try:
295
        orders_pending_local_connection = txnClient.getOrdersNotLocalConnected(provider.id)
296
    except TransactionServiceException as tex:
297
        print tex.message
298
 
299
    try:
300
        if orders_pending_local_connection:
301
            print "Local Connection Pending Orders:"
302
            print orders_pending_local_connection
303
            mismatch_file = "/tmp/BlueDart_LocalConnectionPendingOrders.csv"
304
            print "Some of our Orders were not Shipped to Destination yet. Printing report to:" + mismatch_file
305
            print_undelivered_orders_report(mismatch_file, orders_pending_local_connection)
306
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
307
            mail(from_user, from_pwd, to,\
308
                 "Orders that are not Shipped to Destination yet for " + provider.name,\
309
                 "This is a system generated email.Please don't reply to it.",\
310
                 pickup_mismatch_part)
311
    except Exception:
312
        print "Some issue updating and sending the Local Connection orders report"
313
        traceback.print_exc()
314
 
315
def get_returned_orders(provider):
316
    txnClient = TransactionClient().get_client()
317
    try:
318
        returned_orders = txnClient.getRTOrders(provider.id)
319
    except TransactionServiceException as tex:
320
        print tex.message
321
 
322
    try:
323
        if returned_orders:
324
            print "Returned Orders:"
325
            print returned_orders
326
            returned_orders_file = "/tmp/BlueDart_ReturnedOrders.csv"
327
            print "Some of our Orders were returned by logistics provider. Printing report to:" + returned_orders_file
328
            print_rto_orders_report(returned_orders_file, returned_orders)
329
            returned_orders_report = [get_attachment_part(returned_orders_file)]
330
            mail(from_user, from_pwd, to,\
331
                 "Returned Orders Report for " + provider.name,\
332
                 "This is a system generated email.Please don't reply to it.",\
333
                 returned_orders_report)
334
    except:
335
        print "Some issue sending the returned orders report"
336
        traceback.print_exc()
337
 
338
def get_orders_not_delivered(provider):
339
    txnClient = TransactionClient().get_client()
340
    try:
341
        orders_not_delivered = txnClient.getNonDeliveredOrdersbyCourier(provider.id)
342
    except TransactionServiceException as tex:
343
        print tex.message
344
 
345
    try:
346
        if orders_not_delivered:
347
            print "Undelivered Orders:"
348
            print orders_not_delivered
349
            mismatch_file = "/tmp/BlueDart_UndeliveredOrders.csv"
350
            print "Some of our Orders were not delivered. Printing report to:" + mismatch_file
351
            print_undelivered_orders_report(mismatch_file, orders_not_delivered)
352
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
353
            mail(from_user, from_pwd, to,\
354
                 "Orders that are undelivered but picked up or shipped four days ago for " + provider.name,\
355
                 "This is a system generated email.Please don't reply to it.",\
356
                 pickup_mismatch_part)
357
    except Exception:
358
        print "Some issue updating and sending the undelivered orders report"
359
        traceback.print_exc()
360
 
361
def get_provider_by_name(provider_name):
362
    logistics_client = LogisticsClient().get_client()
363
    provider = None
364
    providers = logistics_client.getAllProviders()
365
    for p in providers:
366
        if p.name == provider_name:
367
            provider=p
368
            break
369
    if provider == None:
370
        sys.exit("Can't continue execution: No such provider")
371
    return provider
372
 
373
def fetch_data(provider_id, order_status_list):
374
    txnClient = TransactionClient().get_client()
375
    try:
376
        doas_tobe_picked_up = txnClient.getOrdersForProviderForStatus(provider_id, order_status_list)
377
        return doas_tobe_picked_up
378
    except TransactionServiceException as tex:
379
        print tex.message
380
 
381
def read_dao_return_pickup_orders(orders_tobe_picked_up):
382
    #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
383
    picked_up_orders = {}
384
    for order in orders_tobe_picked_up:
385
        try:
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=' + str(order.pickupRequestNo)
387
            root = parse(urllib2.urlopen(uri)).getroot()
388
            children = root.getchildren()
389
            for child in children:
390
                nodes = child.findall('Scans/ScanDetail')
391
                for element in reversed(nodes):
392
                    datestring = element.findtext('ScanDate', '')
393
                    timestring = element.findtext('ScanTime', '')
394
                    delivery_date = get_py_datetime(datestring, timestring)
395
                    picked_up_orders[order.pickupRequestNo] = str(delivery_date)
396
                    break
397
                break
398
        except:
399
            pass
400
 
401
    print "Picked up Orders:"
402
    print picked_up_orders
403
    return picked_up_orders
404
 
405
def read_pickup_orders(orders_tobe_picked_up):
406
    picked_up_orders = {}
8699 manish.sha 407
    awb_number_list =[]
6952 rajveer 408
    for order in orders_tobe_picked_up:
8699 manish.sha 409
        awb_number_list.append(order.airwaybill_no)
410
 
411
    track_update_list = get_track_updates(awb_number_list)
412
 
413
    for update in track_update_list:
414
        if update == 'DUMMY':
415
            continue
416
        else:
417
            try:
418
                airwaybill_no = update['ReferenceNo'] 
419
                track_list = update['TrackingList']['TrackingList']
420
                track_list.reverse()
421
                for track_update in track_list:
422
                    if track_update['TrackingCode'] == 'BKD' :
423
                        date_obj = datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
424
                        datestring  = date_obj.strftime("%Y-%m-%d")
425
                        timestring = track_update['ExecutionTime']+':00'
426
                        delivery_date = datestring + timestring
427
                        picked_up_orders[airwaybill_no] = delivery_date
428
                        break
6952 rajveer 429
                break
8699 manish.sha 430
            except:
431
                pass
432
 
6952 rajveer 433
    print "Picked up Orders:"
434
    print picked_up_orders
435
    return picked_up_orders
436
 
437
def read_local_connection_orders(orders_tobe_local_connected):
438
    local_connected_orders = {}
8699 manish.sha 439
 
440
    awb_number_list =[]
6952 rajveer 441
    for order in orders_tobe_local_connected:
8699 manish.sha 442
        awb_number_list.append(order.airwaybill_no)
443
 
444
    track_update_list = get_track_updates(awb_number_list)
445
 
446
    for update in track_update_list:
447
        if update == 'DUMMY':
448
            continue
449
        else:
450
            try:
451
                airwaybill_no = update['ReferenceNo'] 
452
                track_list = update['TrackingList']['TrackingList']
453
                track_list.reverse()
454
                for track_update in track_list:
455
                    if track_update['TrackingCode'] == 'PRO' :
456
                        date_obj = datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
457
                        datestring  = date_obj.strftime("%Y-%m-%d")
458
                        timestring = track_update['ExecutionTime']+':00'
459
                        delivery_date = datestring + timestring
460
                        local_connected_orders[airwaybill_no] = delivery_date
6952 rajveer 461
                        break
462
                break
8699 manish.sha 463
            except:
464
                pass
7025 rajveer 465
 
6952 rajveer 466
    print "Local Connected Orders"
467
    print local_connected_orders
468
 
469
    return local_connected_orders
470
 
471
def read_reached_destination_orders(orders_tobe_reached_destination_city):
472
    destination_city_reached_orders = {}
8699 manish.sha 473
 
474
    awb_number_list =[]
6952 rajveer 475
    for order in orders_tobe_reached_destination_city:
8699 manish.sha 476
        awb_number_list.append(order.airwaybill_no)
477
 
478
    track_update_list = get_track_updates(awb_number_list)
479
 
480
    for update in track_update_list:
481
        if update == 'DUMMY':
482
            continue
483
        else:
484
            try:
485
                airwaybill_no = update['ReferenceNo'] 
486
                track_list = update['TrackingList']['TrackingList']
487
                track_list.reverse()
488
                for track_update in track_list:
489
                    if track_update['TrackingCode'] == 'RDB' :
490
                        date_obj = datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
491
                        datestring  = date_obj.strftime("%Y-%m-%d")
492
                        timestring = track_update['ExecutionTime']+':00'
493
                        delivery_date = datestring + timestring
494
                        destination_city_reached_orders[airwaybill_no] = delivery_date
6952 rajveer 495
                        break
8699 manish.sha 496
                break
497
            except:
498
                pass
6952 rajveer 499
 
500
    print "Destination City Reached Orders"
501
    print destination_city_reached_orders
502
 
503
    return destination_city_reached_orders
504
 
505
def read_first_delivery_attempt_orders(orders_tobe_first_delivery_attempted):
506
    first_atdl_orders = {}
8699 manish.sha 507
 
508
    awb_number_list =[]
6952 rajveer 509
    for order in orders_tobe_first_delivery_attempted:
8699 manish.sha 510
        awb_number_list.append(order.airwaybill_no)
511
 
512
    track_update_list = get_track_updates(awb_number_list)
513
 
514
    for update in track_update_list:
515
        if update == 'DUMMY':
516
            continue
517
        else:
518
            try:
519
                airwaybill_no = update['ReferenceNo'] 
520
                track_list = update['TrackingList']['TrackingList']
521
                track_list.reverse()
522
                for track_update in track_list:
523
                    if track_update['TrackingCode'] == 'OFD' :
524
                        date_obj = datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
525
                        datestring  = date_obj.strftime("%Y-%m-%d")
526
                        timestring = track_update['ExecutionTime']+':00'
527
                        delivery_date = datestring + timestring
528
                        first_atdl_orders[airwaybill_no] = delivery_date
6952 rajveer 529
                        break
7025 rajveer 530
                break
8699 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 = {}
8699 manish.sha 544
    awb_order_map = {}
545
 
6952 rajveer 546
    for order in orders_tobe_delivered:
8699 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
 
8699 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']
561
                track_list.reverse()
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' :
570
                        date_obj = datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
571
                        datestring  = date_obj.strftime("%Y-%m-%d")
572
                        timestring = track_update['ExecutionTime']+':00'
573
                        del_date = datestring + timestring
574
                        delivery_date = datetime.strptime(del_date,"%Y-%m-%d %H:%M:%S")
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' :
582
                        date_obj = datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
583
                        datestring  = date_obj.strftime("%Y-%m-%d")
584
                        timestring = track_update['ExecutionTime']+':00'
585
                        del_date = datestring + timestring
586
                        delivery_date = datetime.strptime(del_date,"%Y-%m-%d %H:%M:%S")
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' :
593
                        date_obj = datetime.strptime(track_update['ExecutionDate'].split(' ')[0],"%m/%d/%Y")
594
                        datestring  = date_obj.strftime("%Y-%m-%d")
595
                        timestring = track_update['ExecutionTime']+':00'
596
                        del_date = datestring + timestring
597
                        delivery_date = datetime.strptime(del_date,"%Y-%m-%d %H:%M:%S")
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
                break
604
            except:
605
                pass
606
 
6952 rajveer 607
    print "Delivered Orders:"
608
    print delivered_orders
609
 
610
    print "Returned Orders:"
611
    print returned_orders
612
 
613
    print "Undelivered Orders"
614
    print undelivered_orders
615
 
616
    return delivered_orders, returned_orders, undelivered_orders
617
 
618
def update_picked_orders(provider_id, pickup_details):
619
    txnClient = TransactionClient().get_client()
620
    try:
621
        txnClient.markOrdersAsPickedUp(provider_id, pickup_details)
622
    except TransactionServiceException as tex:
623
        print tex.message
624
 
625
def update_picked_doas(provider_id, doa_pickup_details):
626
    txnClient = TransactionClient().get_client()
627
    try:
628
        txnClient.markDoasAsPickedUp(provider_id, doa_pickup_details)
629
    except TransactionServiceException as tex:
630
        print tex.message
631
 
632
def update_picked_returns(provider_id, returns_pickup_details):
633
    txnClient = TransactionClient().get_client()
634
    try:
635
        txnClient.markReturnOrdersAsPickedUp(provider_id, returns_pickup_details)
636
    except TransactionServiceException as tex:
637
        print tex.message
638
 
639
def update_delivered_orders(provider_id, delivered_orders):
640
    txnClient = TransactionClient().get_client()
641
    try:
642
        txnClient.markOrdersAsDelivered(provider_id, delivered_orders)
643
    except TransactionServiceException as tex:
644
        print tex.message
645
 
646
def update_returned_orders(provider_id, returned_orders):
647
    txnClient = TransactionClient().get_client()
648
    try:
649
        txnClient.markAsRTOrders(provider_id, returned_orders)
650
    except TransactionServiceException as tex:
651
        print tex.message
652
 
653
def update_reason_of_undelivered_orders(provider_id, undelivered_orders):
654
    txnClient = TransactionClient().get_client()
655
    try:
656
        txnClient.updateNonDeliveryReason(provider_id, undelivered_orders)
657
    except TransactionServiceException as tex:
658
        print tex.message
659
 
660
def update_local_connected_orders(provider_id, local_connected_orders):
661
    txnClient = TransactionClient().get_client()
662
    try:
663
        txnClient.markOrdersAsLocalConnected(provider_id, local_connected_orders)
664
    except TransactionServiceException as tex:
665
        print tex.message
666
 
667
def update_destination_city_reached_orders(provider_id, destination_city_reached_orders):
668
    txnClient = TransactionClient().get_client()
669
    try:
670
        txnClient.markOrdersAsDestinationCityReached(provider_id, destination_city_reached_orders)
671
    except TransactionServiceException as tex:
672
        print tex.message
673
 
674
def update_first_atdl_orders(provider_id, first_atdl_orders):
675
    txnClient = TransactionClient().get_client()
676
    try:
677
        txnClient.markOrdersAsFirstDeliveryAttempted(provider_id, first_atdl_orders)
678
    except TransactionServiceException as tex:
679
        print tex.message
680
 
681
def print_pickup_mismatch_report(filename, orders):
682
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
683
    writer.writerow(['Order Id', 'AWB No', 'Shipping timestamp'])
684
    for order in orders:
685
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.shipping_timestamp)])
686
 
687
def print_dao_return_pickup_mismatch_report(filename, orders):
688
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
689
    writer.writerow(['Order Id', 'Pickup Request No', 'Authorization timestamp'])
690
    for order in orders:
691
        writer.writerow([order.id, order.pickupRequestNo, to_py_date(order.doa_auth_timestamp)])
692
 
693
def print_rto_orders_report(filename, orders):
694
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
695
    writer.writerow(['Order Id', 'AWB No', 'Return date', 'Reason'])
696
    for order in orders:
697
        statusDescription = ''
698
        if order.statusDescription is not None:
699
            statusDescription = order.statusDescription.replace(","," ")
700
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.delivery_timestamp), statusDescription])
701
 
702
def print_undelivered_orders_report(filename, orders):
703
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
704
    writer.writerow(['Order Id', 'AWB No', 'Status', 'Status Description', 'Shipping timestamp', 'Pickup timestamp', 'Promised delivery date', 'Expected delivery date', 'OTG'])
705
    for order in orders:
706
        statusDescription = ''
707
        if order.statusDescription is not None:
708
            statusDescription = order.statusDescription.replace(","," ")
709
        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'])
710
 
711
def create_crm_tickets_for_delivey_attempted_orders(provider):
712
    try:
713
        tickets_tobe_created = fetch_data(provider.id, [OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE])
714
        userClient = UserClient().get_client()
715
        crmServiceClient = CRMClient().get_client()
716
        for order in tickets_tobe_created:
717
            ticket_created = False
718
            searchFilter = SearchFilter()
719
            user = userClient.getUserByEmail(order.customer_email)
720
            if user is None or user.userId == -1:
721
                searchFilter.customerEmailId = order.customer_email
722
                searchFilter.customerMobileNumber = order.customer_mobilenumber
723
            else:
724
                searchFilter.customerId = user.userId
725
            searchFilter.ticketCategory = TicketCategory.UNDELIVERED
726
            tickets = crmServiceClient.getTickets(searchFilter)
727
            print tickets
728
            for old_ticket in tickets:
729
                if old_ticket.orderId == order.id:
730
                    ticket_created = True
731
                    break
732
            if not ticket_created:
733
                print "creating ticket for orderId:"+str(order.id)
734
                ticket = Ticket()
735
                activity = Activity()
736
                description = order.statusDescription + "\n\nOrder not delivered by courier due to problems at customer end."
737
                ticket.creatorId = 1
738
                ticket.assigneeId = defaultUndeliveredAsssigneeId
739
                ticket.category = TicketCategory.UNDELIVERED
740
                ticket.priority = TicketPriority.HIGH
741
                ticket.status = TicketStatus.OPEN
742
                ticket.description = description
743
                ticket.orderId = order.id
744
                ticket.airwayBillNo = order.airwaybill_no
745
 
746
                activity.creatorId = 1
747
                activity.ticketAssigneeId = ticket.assigneeId
748
                activity.type = ActivityType.OTHER
749
                activity.description = description
750
                activity.ticketCategory = ticket.category
751
                activity.ticketDescription = ticket.description
752
                activity.ticketPriority = ticket.priority
753
                activity.ticketStatus = ticket.status
754
 
755
                if user is None or user.userId == -1:
756
                    ticket.customerEmailId = order.customer_email
757
                    ticket.customerMobileNumber = order.customer_mobilenumber
758
                    ticket.customerName = order.customer_name
759
                    activity.customerEmailId = order.customer_email
760
                    activity.customerMobileNumber = order.customer_mobilenumber
761
                    activity.customerName = order.customer_name
762
                else:
763
                    ticket.customerId = user.userId
764
                    activity.customerId = user.userId
765
 
766
                crmServiceClient.insertTicket(ticket, activity)
767
                '''
768
                Inform user about first delivery attempt
769
                '''
770
                enqueueMailForFDA(order)
771
    except:
772
        print "Some issue while creating crm tickets for orders in FIRST_DELIVERY_ATTEMPT_MADE status"
773
        traceback.print_exc()
774
 
775
def auto_close_crm_tickets_created():
776
    try:
777
        ticket_created_orders = []
778
        tickets_map = {}
779
        crmServiceClient = CRMClient().get_client()
780
        searchFilter = SearchFilter()
781
        searchFilter.ticketCategory = TicketCategory.UNDELIVERED
782
        searchFilter.ticketAssigneeIds = [defaultUndeliveredAsssigneeId]
783
        searchFilter.ticketPriority = TicketPriority.HIGH
784
        searchFilter.ticketStatuses = [TicketStatus.OPEN]
785
        tickets = crmServiceClient.getTickets(searchFilter)
786
        print tickets
787
        for old_ticket in tickets:
788
            ticket_created_orders.append(old_ticket.orderId)
789
            tickets_map[old_ticket.orderId] = old_ticket
790
        print ticket_created_orders
791
        txnClient = TransactionClient().get_client()
792
        orders = txnClient.getOrderList(ticket_created_orders)
793
        for order in orders:
794
            if order.status not in [OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
795
                old_ticket = tickets_map.get(order.id)
796
                old_ticket.status = TicketStatus.CLOSED
797
                activity = Activity()
798
                activity.creatorId = 1
799
                activity.ticketAssigneeId = old_ticket.assigneeId
800
                activity.type = ActivityType.OTHER
801
                activity.description = "Ticket Closed bcoz order status changed to:" + order.statusDescription
802
                activity.ticketCategory = old_ticket.category
803
                activity.ticketDescription = old_ticket.description
804
                activity.ticketPriority = old_ticket.priority
805
                activity.ticketStatus = old_ticket.status
806
 
807
                if old_ticket.customerId is None or old_ticket.customerId == -1:
808
                    activity.customerEmailId = old_ticket.customerEmailId
809
                    activity.customerMobileNumber = old_ticket.customerMobileNumber
810
                    activity.customerName = old_ticket.customerName
811
                else:
812
                    activity.customerId = old_ticket.customerId
813
 
814
                crmServiceClient.updateTicket(old_ticket, activity)
815
    except:
816
        print "Some issue while closing crm tickets for orders in DELIVERY_SUCCESS status"
817
        traceback.print_exc()
818
 
819
def get_py_datetime(datestring, timestring):
820
    # This should be a command line argument.
821
    # Refer http://docs.python.org/library/time.html#time.strftime to
822
    # get a complete list of format specifiers available for date time.
823
    if datestring == '':
824
        return None
825
    if datestring.find('-') == -1:
826
        time_format = "%A,%d %B, %Y %H:%M:%S"
827
    else:
828
        time_format = "%d-%b-%Y %H:%M:%S"
829
    if timestring == '':
830
        timestring = '00:00:00'
831
    time_array = timestring.split(':')
832
    if len(time_array) < 3:
833
        timestring = timestring + ':00'
834
    time_string = datestring + ' ' + timestring[0:8]
835
    mytime = time.strptime(time_string, time_format)
836
    return datetime.datetime(*mytime[:6])
837
 
838
 
839
def getTrimedString(text):
840
    if text is None or text == '':
841
        return ''
842
    else:
843
        text = text.strip().lower()
844
        text_list = list(text)
845
        new_text = ''
846
        for letter in text_list:
847
            if letter.isalnum():
848
                new_text = new_text + str(letter)
849
        return new_text
850
 
851
def main():
852
    parser = optparse.OptionParser()
853
    parser.add_option("-p", "--pickup", dest="pickup_report",
854
                   action="store_true",
855
                   help="Run the pickup reconciliation")
856
    parser.add_option("-d", "--delivery", dest="delivery_report",
857
                   action="store_true",
858
                   help="Run the delivery reconciliation")
859
    parser.add_option("-r", "--reports", dest="gen_reports",
860
                   action="store_true",
861
                   help="Generate logistic reconciliation reports")
862
    parser.add_option("-a", "--all", dest="all_reports",
863
                   action="store_true",
864
                   help="Run all reconciliations")
865
    parser.add_option("-P", "--provider", dest="provider",
6966 rajveer 866
                   default="RedExpress", type="string",
6952 rajveer 867
                   help="The PROVIDER this report is for",
868
                   metavar="PROVIDER")
869
    parser.set_defaults(pickup_report=False, delivery_report=False, gen_reports=False, all_reports=False)
870
    (options, args) = parser.parse_args()
871
    if len(args) != 0:
872
        parser.error("You've supplied extra arguments. Are you sure you want to run this program?")
873
 
874
    if options.all_reports:
875
        options.pickup_report = True
876
        options.delivery_report = True
877
 
878
    provider = get_provider_by_name(options.provider)
879
 
880
    if options.pickup_report:
881
        process_pickup_records(provider)
882
        #process_dao_pickup_orders(provider)
883
        #process_return_pickup_orders(provider)
884
    if options.delivery_report:
885
        process_local_connection_orders(provider)
7025 rajveer 886
        process_reached_destination_city_orders(provider)
887
        process_first_delivery_attempt_orders(provider)
6952 rajveer 888
        process_delivery_report(provider)
7025 rajveer 889
        create_crm_tickets_for_delivey_attempted_orders(provider)
890
        auto_close_crm_tickets_created()
6952 rajveer 891
    if options.gen_reports:
892
        generate_reports(provider)
893
 
894
if __name__ == '__main__':
895
    main()