Subversion Repositories SmartDukaan

Rev

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