Subversion Repositories SmartDukaan

Rev

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

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