Subversion Repositories SmartDukaan

Rev

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

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