Subversion Repositories SmartDukaan

Rev

Rev 23228 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
22958 amit.gupta 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 aramex api to know whether they are picked up by aramex
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 aramex api to know whether they are picked up by aramex
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 aramex api to know whether they are picked up by aramex
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 aramex 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.aramex.com/track_xml.asp?ShipperRef={variable1}&OrgCntry=In&FromDate={variable2}&ToDate={variable3} is hard coded
24
to track DOA orders and for other orders ConfigClient is called to get aramex_update_url
25
 
26
@author: Phani Kumar
27
'''
28
from shop2020.clients.CRMClient import CRMClient
29
from shop2020.clients.LogisticsClient import LogisticsClient
30
from shop2020.clients.TransactionClient import TransactionClient
31
from shop2020.clients.UserClient import UserClient
32
from shop2020.config.client.ConfigClient import ConfigClient
33
from shop2020.model.v1.order.script.LogisticUtils import enqueueMailForFDA, \
34
    create_crm_tickets_for_delivey_attempted_orders
35
from shop2020.thriftpy.config.ttypes import ConfigException
36
from shop2020.thriftpy.crm.ttypes import *
37
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \
38
    OrderStatus
39
from shop2020.utils.EmailAttachmentSender import get_attachment_part, mail
40
from shop2020.utils.Utils import to_py_date
41
from xml.etree.ElementTree import parse
42
import csv
43
import datetime
44
import json
45
import optparse
46
import re
47
import sys
48
import time
49
import traceback
50
import urllib
51
import urllib2
52
 
53
if __name__ == '__main__' and __package__ is None:
54
    import os
55
    sys.path.insert(0, os.getcwd())
56
 
57
 
58
try:
59
    config_client = ConfigClient()
60
    RQUICK_URL = config_client.get_property("rquick_update_url")
61
    RQUICK_API_KEY = config_client.get_property("rquick_tracking_api_key")
62
except ConfigException as cex:
63
    print cex.message
64
    traceback.print_exc()
65
 
66
defaultUndeliveredAsssigneeId = 65
23182 amit.gupta 67
#dtrUndeliveredAsssigneeId = 33
22958 amit.gupta 68
from_user = 'cnc.center@shop2020.in'
69
from_pwd = '5h0p2o2o'
23839 amit.gupta 70
to = ["ritesh.chauhan@shop2020.in", "deena.nath@smartdukaan.com"]
22958 amit.gupta 71
 
72
def process_dao_pickup_orders(provider):
73
    try:
74
        doas_tobe_picked_up = fetch_data(provider.id, [OrderStatus.DOA_PICKUP_CONFIRMED])
75
        doa_pickup_details = read_dao_return_pickup_orders(doas_tobe_picked_up)
76
        if doa_pickup_details:
77
            update_picked_doas(provider.id, doa_pickup_details)
78
    except:
79
        print "Some issue while processing the orders in DOA_PICKUP_CONFIRMED status"
80
        traceback.print_exc()
81
 
82
def process_return_pickup_orders(provider):
83
    try:
84
        returns_tobe_picked_up = fetch_data(provider.id, [OrderStatus.RET_PICKUP_CONFIRMED])
85
        returns_pickup_details = read_dao_return_pickup_orders(returns_tobe_picked_up)
86
        if returns_pickup_details:
87
            update_picked_returns(provider.id, returns_pickup_details)
88
    except:
89
        print "Some issue while processing the orders in RET_PICKUP_CONFIRMED status"
90
        traceback.print_exc()
91
 
92
def process_pickup_records(provider):
93
    try:
94
        orders_tobe_picked_up = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH])
95
        pickup_details = read_pickup_orders(orders_tobe_picked_up)
96
        if pickup_details:
97
            update_picked_orders(provider.id, pickup_details)
98
    except:
99
        print "Some issue while processing the orders in SHIPPED_FROM_WH status"
100
        traceback.print_exc()
101
 
102
def process_local_connection_orders(provider):
103
    try:
104
        orders_tobe_local_connected = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST])
105
        local_connected_orders = read_local_connection_orders(orders_tobe_local_connected)
106
        if local_connected_orders:
107
            update_local_connected_orders(provider.id, local_connected_orders)
108
    except:
109
        print "Some issue while processing the orders for local connection status"
110
        traceback.print_exc()
111
 
112
def process_reached_destination_city_orders(provider):
113
    try:
114
        orders_tobe_reached_destination_city = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY])
115
        destination_city_reached_orders = read_reached_destination_orders(orders_tobe_reached_destination_city)
116
        if destination_city_reached_orders:
117
            update_destination_city_reached_orders(provider.id, destination_city_reached_orders)
118
    except:
119
        print "Some issue while processing the orders for Reached Destination City status"
120
        traceback.print_exc()
121
 
122
def process_first_delivery_attempt_orders(provider):
123
    try:
124
        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])
125
        first_atdl_orders = read_first_delivery_attempt_orders(orders_tobe_first_delivery_attempted)
126
        if first_atdl_orders:
127
            update_first_atdl_orders(provider.id, first_atdl_orders)
128
    except:
129
        print "Some issue while processing the orders for First delivery attempt status"
130
        traceback.print_exc()
131
 
132
def process_delivery_report(provider):
133
    try:
134
        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])
135
        delivered_orders, returned_orders, undelivered_orders = read_delivery_orders(orders_tobe_delivered)
136
        if delivered_orders:
137
            update_delivered_orders(provider.id, delivered_orders)
138
        if returned_orders:
139
            update_returned_orders(provider.id, returned_orders)
140
        if undelivered_orders:
141
            update_reason_of_undelivered_orders(provider.id, undelivered_orders)
142
    except:
143
        print "Some issue while processing the orders for delivery status"
144
        traceback.print_exc()
145
 
146
def generate_reports(provider):
147
    #get_doas_not_picked_up(provider)
148
    #get_returns_not_picked_up(provider)
149
    get_orders_not_picked_up(provider)
150
    #get_orders_pending_local_connection(provider)
151
    #get_returned_orders(provider)
152
    get_orders_not_delivered(provider)
153
 
154
def get_doas_not_picked_up(provider):
155
    txnClient = TransactionClient().get_client()
156
    try:
157
        doas_not_picked_up = txnClient.getDoasNotPickedUp(provider.id)
158
    except TransactionServiceException as tex:
159
        print tex.message
160
 
161
    try:
162
        if doas_not_picked_up:
163
            print "DOAs not Picked up:"
164
            print doas_not_picked_up
165
            mismatch_file = "/tmp/Aramex_DoaPickupMismatch.csv"
166
            print "Some of our DOA orders were not picked up. Printing report to:" + mismatch_file
167
            print_dao_return_pickup_mismatch_report(mismatch_file, doas_not_picked_up)
168
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
169
            mail(from_user, from_pwd, to,\
170
                 "DOA Pickup Mismatch for " + provider.name,\
171
                 "This is a system generated email.Please don't reply to it.",\
172
                 pickup_mismatch_part)
173
    except Exception:
174
        print "Some issue sending the DOA mismatch report"
175
        traceback.print_exc()
176
 
177
def get_returns_not_picked_up(provider):
178
    txnClient = TransactionClient().get_client()
179
    try:
180
        returns_not_picked_up = txnClient.getReturnOrdersNotPickedUp(provider.id)
181
    except TransactionServiceException as tex:
182
        print tex.message
183
 
184
    try:
185
        if returns_not_picked_up:
186
            print "Return Orders not Picked up:"
187
            print returns_not_picked_up
188
            mismatch_file = "/tmp/Aramex_ReturnsPickupMismatch.csv"
189
            print "Some of our Return orders were not picked up. Printing report to:" + mismatch_file
190
            print_dao_return_pickup_mismatch_report(mismatch_file, returns_not_picked_up)
191
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
192
            mail(from_user, from_pwd, to,\
193
                 "Return orders Pickup Mismatch for " + provider.name,\
194
                 "This is a system generated email.Please don't reply to it.",\
195
                 pickup_mismatch_part)
196
    except Exception:
197
        print "Some issue sending the Return orders mismatch report"
198
        traceback.print_exc()
199
 
200
def get_orders_not_picked_up(provider):
201
    txnClient = TransactionClient().get_client()
202
    try:
203
        orders_not_picked_up = txnClient.getOrdersNotPickedUp(provider.id)
204
    except TransactionServiceException as tex:
205
        print tex.message
206
 
207
    try:
208
        if orders_not_picked_up:
209
            print "Orders not Picked up:"
210
            print orders_not_picked_up
211
            mismatch_file = "/tmp/Aramex_PickupMismatch.csv"
212
            print "Some of our orders were not picked up. Printing report to:" + mismatch_file
213
            print_pickup_mismatch_report(mismatch_file, orders_not_picked_up)
214
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
215
            mail(from_user, from_pwd, to,\
216
                 "Order Pickup Mismatch for " + provider.name,\
217
                 "This is a system generated email.Please don't reply to it.",\
218
                 pickup_mismatch_part)
219
    except Exception:
220
        print "Some issue sending the pickup mismatch report"
221
        traceback.print_exc()
222
 
223
def get_orders_pending_local_connection(provider):
224
    txnClient = TransactionClient().get_client()
225
    try:
226
        orders_pending_local_connection = txnClient.getOrdersNotLocalConnected(provider.id)
227
    except TransactionServiceException as tex:
228
        print tex.message
229
 
230
    try:
231
        if orders_pending_local_connection:
232
            print "Local Connection Pending Orders:"
233
            print orders_pending_local_connection
234
            mismatch_file = "/tmp/Aramex_LocalConnectionPendingOrders.csv"
235
            print "Some of our Orders were not Shipped to Destination yet. Printing report to:" + mismatch_file
236
            print_undelivered_orders_report(mismatch_file, orders_pending_local_connection)
237
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
238
            mail(from_user, from_pwd, to,\
239
                 "Orders that are not Shipped to Destination yet for " + provider.name,\
240
                 "This is a system generated email.Please don't reply to it.",\
241
                 pickup_mismatch_part)
242
    except Exception:
243
        print "Some issue updating and sending the Local Connection orders report"
244
        traceback.print_exc()
245
 
246
def get_returned_orders(provider):
247
    txnClient = TransactionClient().get_client()
248
    try:
249
        returned_orders = txnClient.getRTOrders(provider.id)
250
    except TransactionServiceException as tex:
251
        print tex.message
252
 
253
    try:
254
        if returned_orders:
255
            print "Returned Orders:"
256
            print returned_orders
257
            returned_orders_file = "/tmp/Aramex_ReturnedOrders.csv"
258
            print "Some of our Orders were returned by logistics provider. Printing report to:" + returned_orders_file
259
            print_rto_orders_report(returned_orders_file, returned_orders)
260
            returned_orders_report = [get_attachment_part(returned_orders_file)]
261
            mail(from_user, from_pwd, to,\
262
                 "Returned Orders Report for " + provider.name,\
263
                 "This is a system generated email.Please don't reply to it.",\
264
                 returned_orders_report)
265
    except:
266
        print "Some issue sending the returned orders report"
267
        traceback.print_exc()
268
 
269
def get_orders_not_delivered(provider):
270
    txnClient = TransactionClient().get_client()
271
    try:
272
        orders_not_delivered = txnClient.getNonDeliveredOrdersbyCourier(provider.id)
273
    except TransactionServiceException as tex:
274
        print tex.message
275
 
276
    try:
277
        if orders_not_delivered:
278
            print "Undelivered Orders:"
279
            print orders_not_delivered
280
            mismatch_file = "/tmp/Aramex_UndeliveredOrders.csv"
281
            print "Some of our Orders were not delivered. Printing report to:" + mismatch_file
282
            print_undelivered_orders_report(mismatch_file, orders_not_delivered)
283
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
284
            mail(from_user, from_pwd, to,\
285
                 "Orders that are undelivered but picked up or shipped four days ago for " + provider.name,\
286
                 "This is a system generated email.Please don't reply to it.",\
287
                 pickup_mismatch_part)
288
    except Exception:
289
        print "Some issue updating and sending the undelivered orders report"
290
        traceback.print_exc()
291
 
292
def get_provider_by_name(provider_name):
293
    logistics_client = LogisticsClient().get_client()
294
    provider = None
295
    providers = logistics_client.getAllProviders()
296
    for p in providers:
297
        if p.name == provider_name:
298
            provider=p
299
            break
300
    if provider == None:
301
        sys.exit("Can't continue execution: No such provider")
302
    return provider
303
 
304
def fetch_data(provider_id, order_status_list):
305
    txnClient = TransactionClient().get_client()
306
    try:
307
        doas_tobe_picked_up = txnClient.getOrdersForProviderForStatus(provider_id, order_status_list)
308
        return doas_tobe_picked_up
309
    except TransactionServiceException as tex:
310
        print tex.message
311
 
312
def read_dao_return_pickup_orders(orders_tobe_picked_up):
313
    #uri=http://www.aramex.com/track_xml.asp?ShipperRef=61582&OrgCntry=In&FromDate=2-6-2012&ToDate=2-6-2012
314
    picked_up_orders = {}
315
    for order in orders_tobe_picked_up:
316
        try:
317
            uri = 'http://www.aramex.com/track_xml.asp?ShipperRef=' + str(order.pickupRequestNo) + '&OrgCntry=In&FromDate=' + to_py_date(order.doa_auth_timestamp).strftime("%m-%d-%Y") +'&ToDate=' + datetime.date.today().strftime("%m-%d-%Y")
318
            root = parse(urllib2.urlopen(uri)).getroot()
319
            nodes = root.findall('HAWBDetails/HAWBHistory/HAWBUpdate')
320
            for element in reversed(nodes):
321
                delivery_date = get_py_datetime(element.findtext('ActionDate', ''))
322
                picked_up_orders[order.pickupRequestNo] = str(delivery_date)
323
                break
324
        except:
325
            pass
326
 
327
    print "Picked up Orders:"
328
    print picked_up_orders
329
    return picked_up_orders
330
 
331
def get_awb_status(awbs):
22996 amit.gupta 332
    awbs = list(set(awbs))
22958 amit.gupta 333
    awbStatuses = {}
334
    if not awbs:
22969 amit.gupta 335
        return awbStatuses
22958 amit.gupta 336
    else:
22996 amit.gupta 337
        doneAwbs = 0
338
        batchSize = 15
339
        while len(awbs) > doneAwbs: 
340
            currentBatch = awbs[doneAwbs:doneAwbs+batchSize]
341
            print "currentBatch", currentBatch
342
            values = { 'api_key': RQUICK_API_KEY, 'awb_no': ",".join(currentBatch)}
343
            data = urllib.urlencode(values)
344
            response = urllib2.urlopen(RQUICK_URL, data)
345
            #print "RQUICK AWB response", response
346
            jsonResponse = json.loads(response.read())
347
            print jsonResponse
348
            if jsonResponse['status']!=1:
349
                print "Invalid api status"
350
            else:
351
                for awbObj in jsonResponse['data']:
352
                    for awb, awbResponse in awbObj.iteritems():
353
                        awbDetails = awbResponse['response']
354
                        awbStatuses[awb] = awbDetails
355
            doneAwbs += batchSize
356
 
22958 amit.gupta 357
 
358
        return awbStatuses       
359
 
360
 
361
 
362
class __AWBStatusObj:
363
    def __init__(self, awb, status, statusDate):
364
        self.awb = awb
365
        self.status = status
366
        self.statusDate = statusDate
367
 
368
 
369
 
370
def read_pickup_orders(orders_tobe_picked_up):
371
    picked_up_orders = {}
372
    awbs = [order.airwaybill_no for order in orders_tobe_picked_up]
373
 
22962 amit.gupta 374
    for awb, awbDetails in get_awb_status(awbs).iteritems():
22958 amit.gupta 375
        #status = awbDetails['Status']
376
        #statusDate = get_pawbDetails['StatusDateTime']
22966 amit.gupta 377
        print awbDetails
22958 amit.gupta 378
        tracking = awbDetails['Tracking']
379
        bookedTime = get_py_datetime(tracking[-1]['StatusDateTime'])
380
        picked_up_orders[awb] = str(bookedTime)
381
    print "Picked up Orders:"
382
    print picked_up_orders
383
    return picked_up_orders
384
 
385
def read_local_connection_orders(orders_tobe_local_connected):
386
 
387
    local_connected_orders = {}
388
    awbs = [order.airwaybill_no for order in orders_tobe_local_connected]
389
 
22966 amit.gupta 390
    for awb, awbDetails in get_awb_status(awbs).iteritems():
22958 amit.gupta 391
        #status = awbDetails['Status']
392
        #statusDate = get_pawbDetails['StatusDateTime']
393
        tracking = awbDetails['Tracking']
394
        bookedTime = get_py_datetime(tracking[-1]['StatusDateTime'])
395
        local_connected_orders[awb] = str(bookedTime)
396
 
397
    print "Local Connected Orders"
398
    print local_connected_orders
399
 
400
    return local_connected_orders
401
 
402
def read_reached_destination_orders(orders_tobe_reached_destination_city):
403
    destination_city_reached_orders = {}
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 = {}
23053 amit.gupta 412
    awbs = [order.airwaybill_no for order in orders_tobe_first_delivery_attempted]
413
    for awb, awbDetails in get_awb_status(awbs).iteritems():
414
        status = awbDetails['Status']
23228 amit.gupta 415
        print "AWB-----", awb, "STATUS -----", status
23054 amit.gupta 416
        if status.startswith("Undelivered"):
417
            statusTime = get_py_datetime(awbDetails['StatusDateTime'])
23057 amit.gupta 418
            first_atdl_orders[awb] = str(statusTime) + "|" + awbDetails['Status']
23056 amit.gupta 419
    print "FIRST DELIVERY ATTEMPT MADE Orders", first_atdl_orders
22958 amit.gupta 420
    print first_atdl_orders
421
 
422
    return first_atdl_orders
423
 
424
def read_delivery_orders(orders_tobe_delivered):
425
    delivered_orders = {}
426
    returned_orders = {}
427
    undelivered_orders = {}
428
 
429
    awbs = [order.airwaybill_no for order in orders_tobe_delivered]
430
 
22966 amit.gupta 431
    for awb, awbDetails in get_awb_status(awbs).iteritems():
22958 amit.gupta 432
        status = awbDetails['Status']
433
        statusTime = get_py_datetime(awbDetails['StatusDateTime'])
434
        #statusDate = awbDetails['StatusDateTime']
435
        #tracking = awbDetails['Tracking']
436
        if status.startswith("Delivered"):
437
            delivered_orders[awb] = str(statusTime) + "|" +  "Not Available"
438
 
22970 amit.gupta 439
        if status.startswith('RTO'):
22983 amit.gupta 440
            returned_orders[awb] = str(statusTime) + "|" + "Not Available"
22958 amit.gupta 441
 
22983 amit.gupta 442
        undelivered_orders[awb] = status
22958 amit.gupta 443
 
444
    print "Delivered Orders:"
445
    print delivered_orders
446
 
447
    print "Returned Orders:"
448
    print returned_orders
449
 
450
    print "Undelivered Orders"
451
    print undelivered_orders
452
 
453
    return delivered_orders, returned_orders, undelivered_orders
454
 
455
def update_picked_orders(provider_id, pickup_details):
456
    txnClient = TransactionClient().get_client()
457
    try:
458
        txnClient.markOrdersAsPickedUp(provider_id, pickup_details)
459
    except TransactionServiceException as tex:
460
        print tex.message
461
 
462
def update_picked_doas(provider_id, doa_pickup_details):
463
    txnClient = TransactionClient().get_client()
464
    try:
465
        txnClient.markDoasAsPickedUp(provider_id, doa_pickup_details)
466
    except TransactionServiceException as tex:
467
        print tex.message
468
 
469
def update_picked_returns(provider_id, returns_pickup_details):
470
    txnClient = TransactionClient().get_client()
471
    try:
472
        txnClient.markReturnOrdersAsPickedUp(provider_id, returns_pickup_details)
473
    except TransactionServiceException as tex:
474
        print tex.message
475
 
476
def update_delivered_orders(provider_id, delivered_orders):
477
    txnClient = TransactionClient().get_client()
478
    try:
479
        txnClient.markOrdersAsDelivered(provider_id, delivered_orders)
480
    except TransactionServiceException as tex:
481
        print tex.message
482
 
483
def update_returned_orders(provider_id, returned_orders):
484
    txnClient = TransactionClient().get_client()
485
    try:
486
        txnClient.markAsRTOrders(provider_id, returned_orders)
487
    except TransactionServiceException as tex:
488
        print tex.message
489
 
490
def update_reason_of_undelivered_orders(provider_id, undelivered_orders):
491
    txnClient = TransactionClient().get_client()
492
    try:
493
        txnClient.updateNonDeliveryReason(provider_id, undelivered_orders)
494
    except TransactionServiceException as tex:
495
        print tex.message
496
 
497
def update_local_connected_orders(provider_id, local_connected_orders):
498
    txnClient = TransactionClient().get_client()
499
    try:
500
        txnClient.markOrdersAsLocalConnected(provider_id, local_connected_orders)
501
    except TransactionServiceException as tex:
502
        print tex.message
503
 
504
def update_destination_city_reached_orders(provider_id, destination_city_reached_orders):
505
    txnClient = TransactionClient().get_client()
506
    try:
507
        txnClient.markOrdersAsDestinationCityReached(provider_id, destination_city_reached_orders)
508
    except TransactionServiceException as tex:
509
        print tex.message
510
 
511
def update_first_atdl_orders(provider_id, first_atdl_orders):
512
    txnClient = TransactionClient().get_client()
513
    try:
514
        txnClient.markOrdersAsFirstDeliveryAttempted(provider_id, first_atdl_orders)
515
    except TransactionServiceException as tex:
516
        print tex.message
517
 
518
def print_pickup_mismatch_report(filename, orders):
519
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
520
    writer.writerow(['Order Id', 'AWB No', 'Shipping timestamp'])
521
    for order in orders:
522
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.shipping_timestamp)])
523
 
524
def print_dao_return_pickup_mismatch_report(filename, orders):
525
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
526
    writer.writerow(['Order Id', 'Pickup Request No', 'Authorization timestamp'])
527
    for order in orders:
528
        writer.writerow([order.id, order.pickupRequestNo, to_py_date(order.doa_auth_timestamp)])
529
 
530
def print_rto_orders_report(filename, orders):
531
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
532
    writer.writerow(['Order Id', 'AWB No', 'Return date', 'Reason'])
533
    for order in orders:
534
        statusDescription = ''
535
        if order.statusDescription is not None:
536
            statusDescription = order.statusDescription.replace(","," ")
537
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.delivery_timestamp), statusDescription])
538
 
539
def print_undelivered_orders_report(filename, orders):
540
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
541
    writer.writerow(['Order Id', 'AWB No', 'Status', 'Status Description', 'Shipping timestamp', 'Pickup timestamp', 'Promised delivery date', 'Expected delivery date'])
542
    for order in orders:
543
        statusDescription = ''
544
        if order.statusDescription is not None:
545
            statusDescription = order.statusDescription.replace(","," ")
546
        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)])
547
 
548
def auto_close_crm_tickets_created():
549
    try:
550
        ticket_created_orders = []
551
        tickets_map = {}
552
        crmServiceClient = CRMClient().get_client()
553
        searchFilter = SearchFilter()
554
        searchFilter.ticketCategory = TicketCategory.UNDELIVERED
555
        searchFilter.ticketAssigneeIds = [defaultUndeliveredAsssigneeId]
556
        searchFilter.ticketPriority = TicketPriority.HIGH
557
        searchFilter.ticketStatuses = [TicketStatus.OPEN]
558
        tickets = crmServiceClient.getTickets(searchFilter)
559
        print tickets
560
        for old_ticket in tickets:
561
            ticket_created_orders.append(old_ticket.orderId)
562
            tickets_map[old_ticket.orderId] = old_ticket
563
        print ticket_created_orders
564
        txnClient = TransactionClient().get_client()
565
        orders = txnClient.getOrderList(ticket_created_orders)
566
        for order in orders:
567
            if order.status not in [OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.RTO_IN_TRANSIT]:
568
                old_ticket = tickets_map.get(order.id)
569
                old_ticket.status = TicketStatus.CLOSED
570
                activity = Activity()
571
                activity.creatorId = 1
572
                activity.ticketAssigneeId = old_ticket.assigneeId
573
                activity.type = ActivityType.OTHER
574
                activity.description = "Ticket Closed bcoz order status changed to:" + order.statusDescription
575
                activity.ticketCategory = old_ticket.category
576
                activity.ticketDescription = old_ticket.description
577
                activity.ticketPriority = old_ticket.priority
578
                activity.ticketStatus = old_ticket.status
579
 
580
                if old_ticket.customerId is None or old_ticket.customerId == -1:
581
                    activity.customerEmailId = old_ticket.customerEmailId
582
                    activity.customerMobileNumber = old_ticket.customerMobileNumber
583
                    activity.customerName = old_ticket.customerName
584
                else:
585
                    activity.customerId = old_ticket.customerId
586
 
587
                crmServiceClient.updateTicket(old_ticket, activity)
588
    except:
589
        print "Some issue while closing crm tickets for orders in DELIVERY_SUCCESS status"
590
        traceback.print_exc()
591
 
592
def get_py_datetime(time_string):
593
    # This should be a command line argument.
594
    # Refer http://docs.python.org/library/time.html#time.strftime to
595
    # get a complete list of format specifiers available for date time.
596
    time_format = "%d-%m-%Y %H:%M:%S"
597
    if time_string == '':
598
        return None
599
    return datetime.datetime.strptime(time_string, time_format)
600
 
601
def getOriginCityBranchID(originCity):
602
    branchId_OriginCitymap = {'DEL':'7933'}
603
    if originCity is None or originCity == '':
604
        return ''
605
    else:
606
        return branchId_OriginCitymap.get(originCity)
607
 
608
def sanitizeUnicode(unicodeText):
609
    #remove unicode characters
610
    unicodeText = re.sub(r'[^\x00-\x7F]+','', unicodeText)
611
    #remove whitespaces and strip
612
    unicodeText = re.sub(r'[^\S]+',' ', unicodeText)
613
    return unicodeText.strip().encode('utf-8', 'ignore')
614
 
615
def main():
616
    parser = optparse.OptionParser()
617
    parser.add_option("-p", "--pickup", dest="pickup_report",
618
                   action="store_true",
619
                   help="Run the pickup reconciliation")
620
    parser.add_option("-d", "--delivery", dest="delivery_report",
621
                   action="store_true",
622
                   help="Run the delivery reconciliation")
623
    parser.add_option("-r", "--reports", dest="gen_reports",
624
                   action="store_true",
625
                   help="Generate logistic reconciliation reports")
626
    parser.add_option("-a", "--all", dest="all_reports",
627
                   action="store_true",
628
                   help="Run all reconciliations")
629
    parser.add_option("-P", "--provider", dest="provider",
22960 amit.gupta 630
                   default="RQuick-Express", type="string",
22958 amit.gupta 631
                   help="The PROVIDER this report is for",
632
                   metavar="PROVIDER")
633
    parser.set_defaults(pickup_report=False, delivery_report=False, gen_reports=False, all_reports=False)
634
    (options, args) = parser.parse_args()
635
    if len(args) != 0:
636
        parser.error("You've supplied extra arguments. Are you sure you want to run this program?")
637
 
638
    if options.all_reports:
639
        options.pickup_report = True
640
        options.delivery_report = True
641
 
642
    provider = get_provider_by_name(options.provider)
643
 
644
    if options.pickup_report:
645
        process_pickup_records(provider)
646
        #process_dao_pickup_orders(provider)
647
        #process_return_pickup_orders(provider)
648
    if options.delivery_report:
23058 amit.gupta 649
        #process_local_connection_orders(provider)
22958 amit.gupta 650
        #process_reached_destination_city_orders(provider)
23053 amit.gupta 651
        process_first_delivery_attempt_orders(provider)
22958 amit.gupta 652
        process_delivery_report(provider)
653
        #create_crm_tickets_for_delivey_attempted_orders(provider)
654
        #auto_close_crm_tickets_created()
655
    if options.gen_reports:
22959 amit.gupta 656
        pass
657
        #generate_reports(provider)
22958 amit.gupta 658
 
659
if __name__ == '__main__':
660
    main()