Subversion Repositories SmartDukaan

Rev

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