Subversion Repositories SmartDukaan

Rev

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