Subversion Repositories SmartDukaan

Rev

Rev 5325 | Go to most recent revision | Details | 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 = {}
305
    for order in orders_tobe_picked_up:
306
        try:
307
            uri = Delhivery_URL + 'ref_nos=' + str(order.pickupRequestNo)
308
            root = parse(urllib2.urlopen(uri)).getroot()
309
            nodes = root.findall('Shipment/Scans/ScanDetail')
310
            for element in nodes:
311
                delivery_date = get_py_datetime(element.findtext('ScanDateTime', ''))
312
                picked_up_orders[order.pickupRequestNo] = str(delivery_date)
313
                break
314
        except:
315
            pass
316
 
317
    print "Picked up Orders:"
318
    print picked_up_orders
319
    return picked_up_orders
320
 
321
def read_pickup_orders(orders_tobe_picked_up):
322
    picked_up_orders = {}
323
    for order in orders_tobe_picked_up:
324
        try:
325
            uri = Delhivery_URL + 'waybill=' + order.airwaybill_no
326
            root = parse(urllib2.urlopen(uri)).getroot()
327
            nodes = root.findall('Shipment/Scans/ScanDetail')
328
            for element in nodes:
329
                delivery_date = get_py_datetime(element.findtext('ScanDateTime', ''))
330
                picked_up_orders[order.airwaybill_no] = str(delivery_date)
331
                break
332
        except:
333
            pass
334
 
335
    print "Picked up Orders:"
336
    print picked_up_orders
337
    return picked_up_orders
338
 
339
def read_local_connection_orders(orders_tobe_local_connected):
340
    local_connected_orders = {}
341
    for order in orders_tobe_local_connected:
342
        try:
343
            uri = Delhivery_URL + 'waybill=' + order.airwaybill_no
344
            root = parse(urllib2.urlopen(uri)).getroot()
345
            nodes = root.findall('Shipment/Scans/ScanDetail')
346
            for element in nodes:
347
                if element.findtext('ScanType', '') == 'UD' and getTrimedString(element.findtext('Scan', '')) == getTrimedString('In Transit'):
348
                    delivery_date = get_py_datetime(element.findtext('ScanDateTime', ''))
349
                    local_connected_orders[order.airwaybill_no] = str(delivery_date)
350
                    break
351
        except:
352
            pass
353
 
354
    print "Local Connected Orders"
355
    print local_connected_orders
356
 
357
    return local_connected_orders
358
 
359
def read_reached_destination_orders(orders_tobe_reached_destination_city):
360
    destination_city_reached_orders = {}
361
    for order in orders_tobe_reached_destination_city:
362
        try:
363
            uri = Delhivery_URL + 'waybill=' + order.airwaybill_no
364
            root = parse(urllib2.urlopen(uri)).getroot()
365
            nodes = root.findall('Shipment/Scans/ScanDetail')
366
            for element in nodes:
367
                if element.findtext('ScanType', '') == 'UD' and getTrimedString(element.findtext('Scan', '')) == getTrimedString('Pending'):
368
                    delivery_date = get_py_datetime(element.findtext('ScanDateTime', ''))
369
                    destination_city_reached_orders[order.airwaybill_no] = str(delivery_date)
370
                    break
371
        except:
372
            pass
373
 
374
    print "Destination City Reached Orders"
375
    print destination_city_reached_orders
376
 
377
    return destination_city_reached_orders
378
 
379
def read_first_delivery_attempt_orders(orders_tobe_first_delivery_attempted):
380
    first_atdl_orders = {}
381
    for order in orders_tobe_first_delivery_attempted:
382
        try:
383
            uri = Delhivery_URL + 'waybill=' + order.airwaybill_no
384
            root = parse(urllib2.urlopen(uri)).getroot()
385
            nodes = root.findall('Shipment/Scans/ScanDetail')
386
            node_number = 0
387
            for element in nodes:
388
                if element.findtext('ScanType', '') == 'UD' and getTrimedString(element.findtext('Scan', '')) == getTrimedString('Dispatched'):
389
                    if node_number != len(nodes)-1 and nodes[node_number+1].findtext('ScanType', '') == 'UD':
390
                        element = nodes[node_number+1]
391
                        delivery_date = get_py_datetime(element.findtext('ScanDateTime', ''))
392
                        reason_for_nondelivery = element.findtext('Instructions', '')
393
                        first_atdl_orders[order.airwaybill_no] = str(delivery_date) + "|" + reason_for_nondelivery
394
                        break
395
                node_number = node_number + 1
396
        except:
397
            pass
398
 
399
    print "FIRST DELIVERY ATTEMPT MADE Orders"
400
    print first_atdl_orders
401
 
402
    return first_atdl_orders
403
 
404
def read_delivery_orders(orders_tobe_delivered):
405
    delivered_orders = {}
406
    returned_orders = {}
407
    undelivered_orders = {}
408
    for order in orders_tobe_delivered:
409
        try:
410
            uri = Delhivery_URL + 'waybill=' + order.airwaybill_no
411
            root = parse(urllib2.urlopen(uri)).getroot()
412
            nodes = root.findall('Shipment/Scans/ScanDetail')
413
            node_number = 0
414
            for element in nodes:
415
                if element.findtext('ScanType', '') == 'DL' and getTrimedString(element.findtext('Scan', '')) == getTrimedString('Delivered'):
416
                    delivery_date = get_py_datetime(element.findtext('ScanDateTime', ''))
417
                    receiver = root.findtext('Shipment/Status/RecievedBy', '')
418
                    delivered_orders[order.airwaybill_no] = str(delivery_date) + "|" +  receiver
419
                    break
420
                elif element.findtext('ScanType', '') == 'RT' and getTrimedString(element.findtext('Scan', '')) == getTrimedString('Returned'):
421
                    delivery_date = get_py_datetime(element.findtext('ScanDateTime', ''))
422
                    reason_for_return = element.findtext('Instructions', '')
423
                    returned_orders[order.airwaybill_no] = str(delivery_date) + "|" + reason_for_return
424
                    break
425
                elif node_number == len(nodes)-1:
426
                    reason = element.findtext('Instructions', '')
427
                    undelivered_orders[order.airwaybill_no] = reason
428
                    break
429
                node_number = node_number + 1
430
        except:
431
            pass
432
 
433
    print "Delivered Orders:"
434
    print delivered_orders
435
 
436
    print "Returned Orders:"
437
    print returned_orders
438
 
439
    print "Undelivered Orders"
440
    print undelivered_orders
441
 
442
    return delivered_orders, returned_orders, undelivered_orders
443
 
444
def update_picked_orders(provider_id, pickup_details):
445
    txnClient = TransactionClient().get_client()
446
    try:
447
        txnClient.markOrdersAsPickedUp(provider_id, pickup_details)
448
    except TransactionServiceException as tex:
449
        print tex.message
450
 
451
def update_picked_doas(provider_id, doa_pickup_details):
452
    txnClient = TransactionClient().get_client()
453
    try:
454
        txnClient.markDoasAsPickedUp(provider_id, doa_pickup_details)
455
    except TransactionServiceException as tex:
456
        print tex.message
457
 
458
def update_picked_returns(provider_id, returns_pickup_details):
459
    txnClient = TransactionClient().get_client()
460
    try:
461
        txnClient.markReturnOrdersAsPickedUp(provider_id, returns_pickup_details)
462
    except TransactionServiceException as tex:
463
        print tex.message
464
 
465
def update_delivered_orders(provider_id, delivered_orders):
466
    txnClient = TransactionClient().get_client()
467
    try:
468
        txnClient.markOrdersAsDelivered(provider_id, delivered_orders)
469
    except TransactionServiceException as tex:
470
        print tex.message
471
 
472
def update_returned_orders(provider_id, returned_orders):
473
    txnClient = TransactionClient().get_client()
474
    try:
475
        txnClient.markAsRTOrders(provider_id, returned_orders)
476
    except TransactionServiceException as tex:
477
        print tex.message
478
 
479
def update_reason_of_undelivered_orders(provider_id, undelivered_orders):
480
    txnClient = TransactionClient().get_client()
481
    try:
482
        txnClient.updateNonDeliveryReason(provider_id, undelivered_orders)
483
    except TransactionServiceException as tex:
484
        print tex.message
485
 
486
def update_local_connected_orders(provider_id, local_connected_orders):
487
    txnClient = TransactionClient().get_client()
488
    try:
489
        txnClient.markOrdersAsLocalConnected(provider_id, local_connected_orders)
490
    except TransactionServiceException as tex:
491
        print tex.message
492
 
493
def update_destination_city_reached_orders(provider_id, destination_city_reached_orders):
494
    txnClient = TransactionClient().get_client()
495
    try:
496
        txnClient.markOrdersAsDestinationCityReached(provider_id, destination_city_reached_orders)
497
    except TransactionServiceException as tex:
498
        print tex.message
499
 
500
def update_first_atdl_orders(provider_id, first_atdl_orders):
501
    txnClient = TransactionClient().get_client()
502
    try:
503
        txnClient.markOrdersAsFirstDeliveryAttempted(provider_id, first_atdl_orders)
504
    except TransactionServiceException as tex:
505
        print tex.message
506
 
507
def print_pickup_mismatch_report(filename, orders):
508
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
509
    writer.writerow(['Order Id', 'AWB No', 'Shipping timestamp'])
510
    for order in orders:
511
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.shipping_timestamp)])
512
 
513
def print_dao_return_pickup_mismatch_report(filename, orders):
514
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
515
    writer.writerow(['Order Id', 'Pickup Request No', 'Authorization timestamp'])
516
    for order in orders:
517
        writer.writerow([order.id, order.pickupRequestNo, to_py_date(order.doa_auth_timestamp)])
518
 
519
def print_rto_orders_report(filename, orders):
520
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
521
    writer.writerow(['Order Id', 'AWB No', 'Return date', 'Reason'])
522
    for order in orders:
523
        statusDescription = ''
524
        if order.statusDescription is not None:
525
            statusDescription = order.statusDescription.replace(","," ")
526
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.delivery_timestamp), statusDescription])
527
 
528
def print_undelivered_orders_report(filename, orders):
529
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
530
    writer.writerow(['Order Id', 'AWB No', 'Status', 'Status Description', 'Shipping timestamp', 'Pickup timestamp', 'Promised delivery date', 'Expected delivery date'])
531
    for order in orders:
532
        statusDescription = ''
533
        if order.statusDescription is not None:
534
            statusDescription = order.statusDescription.replace(","," ")
535
        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)])
536
 
537
def create_crm_tickets_for_delivey_attempted_orders(provider):
538
    try:
539
        tickets_tobe_created = fetch_data(provider.id, [OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE])
540
        userClient = UserClient().get_client()
541
        crmServiceClient = CRMClient().get_client()
542
        for order in tickets_tobe_created:
543
            ticket_created = False
544
            searchFilter = SearchFilter()
545
            user = userClient.getUserByEmail(order.customer_email)
546
            if user is None or user.userId == -1:
547
                searchFilter.customerEmailId = order.customer_email
548
                searchFilter.customerMobileNumber = order.customer_mobilenumber
549
            else:
550
                searchFilter.customerId = user.userId
551
            searchFilter.ticketCategory = TicketCategory.UNDELIVERED
552
            tickets = crmServiceClient.getTickets(searchFilter)
553
            print tickets
554
            for old_ticket in tickets:
555
                if old_ticket.orderId == order.id:
556
                    ticket_created = True
557
                    break
558
            if not ticket_created:
559
                print "creating ticket for orderId:"+str(order.id)
560
                ticket = Ticket()
561
                activity = Activity()
562
                description = order.statusDescription + "\n\nOrder not delivered by courier due to problems at customer end."
563
                ticket.creatorId = 1
564
                ticket.assigneeId = defaultUndeliveredAsssigneeId
565
                ticket.category = TicketCategory.UNDELIVERED
566
                ticket.priority = TicketPriority.HIGH
567
                ticket.status = TicketStatus.OPEN
568
                ticket.description = description
569
                ticket.orderId = order.id
570
                ticket.airwayBillNo = order.airwaybill_no
571
 
572
                activity.creatorId = 1
573
                activity.ticketAssigneeId = ticket.assigneeId
574
                activity.type = ActivityType.OTHER
575
                activity.description = description
576
                activity.ticketCategory = ticket.category
577
                activity.ticketDescription = ticket.description
578
                activity.ticketPriority = ticket.priority
579
                activity.ticketStatus = ticket.status
580
 
581
                if user is None or user.userId == -1:
582
                    ticket.customerEmailId = order.customer_email
583
                    ticket.customerMobileNumber = order.customer_mobilenumber
584
                    ticket.customerName = order.customer_name
585
                    activity.customerEmailId = order.customer_email
586
                    activity.customerMobileNumber = order.customer_mobilenumber
587
                    activity.customerName = order.customer_name
588
                else:
589
                    ticket.customerId = user.userId
590
                    activity.customerId = user.userId
591
 
592
                crmServiceClient.insertTicket(ticket, activity)
593
    except:
594
        print "Some issue while creating crm tickets for orders in FIRST_DELIVERY_ATTEMPT_MADE status"
595
        traceback.print_exc()
596
 
597
def auto_close_crm_tickets_created():
598
    try:
599
        ticket_created_orders = []
600
        tickets_map = {}
601
        crmServiceClient = CRMClient().get_client()
602
        searchFilter = SearchFilter()
603
        searchFilter.ticketCategory = TicketCategory.UNDELIVERED
604
        searchFilter.ticketAssigneeIds = [defaultUndeliveredAsssigneeId]
605
        searchFilter.ticketPriority = TicketPriority.HIGH
606
        searchFilter.ticketStatuses = [TicketStatus.OPEN]
607
        tickets = crmServiceClient.getTickets(searchFilter)
608
        print tickets
609
        for old_ticket in tickets:
610
            ticket_created_orders.append(old_ticket.orderId)
611
            tickets_map[old_ticket.orderId] = old_ticket
612
        print ticket_created_orders
613
        txnClient = TransactionClient().get_client()
614
        orders = txnClient.getOrderList(ticket_created_orders)
615
        for order in orders:
616
            if order.status not in [OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
617
                old_ticket = tickets_map.get(order.id)
618
                old_ticket.status = TicketStatus.CLOSED
619
                activity = Activity()
620
                activity.creatorId = 1
621
                activity.ticketAssigneeId = old_ticket.assigneeId
622
                activity.type = ActivityType.OTHER
623
                activity.description = "Ticket Closed bcoz order status changed to:" + order.statusDescription
624
                activity.ticketCategory = old_ticket.category
625
                activity.ticketDescription = old_ticket.description
626
                activity.ticketPriority = old_ticket.priority
627
                activity.ticketStatus = old_ticket.status
628
 
629
                if old_ticket.customerId is None or old_ticket.customerId == -1:
630
                    activity.customerEmailId = old_ticket.customerEmailId
631
                    activity.customerMobileNumber = old_ticket.customerMobileNumber
632
                    activity.customerName = old_ticket.customerName
633
                else:
634
                    activity.customerId = old_ticket.customerId
635
 
636
                crmServiceClient.updateTicket(old_ticket, activity)
637
    except:
638
        print "Some issue while closing crm tickets for orders in DELIVERY_SUCCESS status"
639
        traceback.print_exc()
640
 
641
def get_py_datetime(time_string):
642
    # This should be a command line argument.
643
    # Refer http://docs.python.org/library/time.html#time.strftime to
644
    # get a complete list of format specifiers available for date time.
645
    time_format = "%Y-%m-%d %H:%M:%S"
646
    if time_string == '':
647
        return None
648
    date_time_array = time_string.split('T')
649
    datestring = date_time_array[0]
650
    timestring = date_time_array[1]
651
    if timestring == '':
652
        timestring = '00:00:00'
653
    else:
654
        timestring = timestring.split('.')[0]
655
    time_string = datestring + ' ' + timestring
656
    mytime = time.strptime(time_string, time_format)
657
    return datetime.datetime(*mytime[:6])
658
 
659
def getTrimedString(text):
660
    if text is None or text == '':
661
        return ''
662
    else:
663
        text = text.strip().lower()
664
        text_list = list(text)
665
        new_text = ''
666
        for letter in text_list:
667
            if letter.isalnum():
668
                new_text = new_text + str(letter)
669
        return new_text
670
 
671
def main():
672
    parser = optparse.OptionParser()
673
    parser.add_option("-p", "--pickup", dest="pickup_report",
674
                   action="store_true",
675
                   help="Run the pickup reconciliation")
676
    parser.add_option("-d", "--delivery", dest="delivery_report",
677
                   action="store_true",
678
                   help="Run the delivery reconciliation")
679
    parser.add_option("-r", "--reports", dest="gen_reports",
680
                   action="store_true",
681
                   help="Generate logistic reconciliation reports")
682
    parser.add_option("-a", "--all", dest="all_reports",
683
                   action="store_true",
684
                   help="Run all reconciliations")
685
    parser.add_option("-P", "--provider", dest="provider",
686
                   default="Delhivery", type="string",
687
                   help="The PROVIDER this report is for",
688
                   metavar="PROVIDER")
689
    parser.set_defaults(pickup_report=False, delivery_report=False, gen_reports=False, all_reports=False)
690
    (options, args) = parser.parse_args()
691
    if len(args) != 0:
692
        parser.error("You've supplied extra arguments. Are you sure you want to run this program?")
693
 
694
    if options.all_reports:
695
        options.pickup_report = True
696
        options.delivery_report = True
697
 
698
    provider = get_provider_by_name(options.provider)
699
 
700
    if options.pickup_report:
701
        process_pickup_records(provider)
702
        process_dao_pickup_orders(provider)
703
        process_return_pickup_orders(provider)
704
    if options.delivery_report:
705
        process_local_connection_orders(provider)
706
        process_reached_destination_city_orders(provider)
707
        process_first_delivery_attempt_orders(provider)
708
        process_delivery_report(provider)
709
        create_crm_tickets_for_delivey_attempted_orders(provider)
710
        auto_close_crm_tickets_created()
711
    if options.gen_reports:
712
        generate_reports(provider)
713
 
714
if __name__ == '__main__':
715
    main()