Subversion Repositories SmartDukaan

Rev

Rev 23250 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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