Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
4506 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 aramex api to know whether they are picked up by armaex
7
     and changes the status to DOA_RETURN_IN_TRANSIT if it is done.
4741 phani.kuma 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 armaex
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
4506 phani.kuma 13
     were in SHIPPED_FROM_WH status from database and 
14
     calls aramex api to know whether they are picked up by armaex
15
     and changes the status to SHIPPED_TO_LOGST if it is done.
4741 phani.kuma 16
 4. Orders in SHIPPED_TO_LOGST status: get details of orders that
4506 phani.kuma 17
     were in SHIPPED_TO_LOGST status from database and 
18
     calls aramex api to know their status and changes the status accordingly.
19
 
4741 phani.kuma 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
4506 phani.kuma 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
import time
29
import datetime
30
import optparse
31
import sys
32
import csv
33
import traceback
34
import urllib2
35
from xml.etree.ElementTree import parse
36
 
37
if __name__ == '__main__' and __package__ is None:
38
    import os
39
    sys.path.insert(0, os.getcwd())
40
 
41
from shop2020.clients.LogisticsClient import LogisticsClient
42
from shop2020.clients.TransactionClient import TransactionClient
43
from shop2020.config.client.ConfigClient import ConfigClient
44
from shop2020.thriftpy.config.ttypes import ConfigException
45
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, OrderStatus
46
from shop2020.utils.EmailAttachmentSender import get_attachment_part, mail
47
from shop2020.utils.Utils import to_py_date
48
 
49
from_user = 'cnc.center@shop2020.in'
50
from_pwd = '5h0p2o2o'
4760 phani.kuma 51
to = ['cnc.center@shop2020.in', "suraj.sharma@shop2020.in", "sandeep.sachdeva@shop2020.in", "manoj.kumar@shop2020.in"]
4506 phani.kuma 52
 
53
def process_dao_pickup_orders(provider):
54
    try:
4559 phani.kuma 55
        doas_tobe_picked_up = fetch_data(provider.id, OrderStatus.DOA_PICKUP_CONFIRMED)
4741 phani.kuma 56
        doa_pickup_details = read_dao_return_pickup_orders(doas_tobe_picked_up)
4559 phani.kuma 57
        doas_not_picked_up = update_picked_doas(provider.id, doa_pickup_details)
58
        try:
59
            if doas_not_picked_up:
60
                print "DOAs not Picked up:"
61
                print doas_not_picked_up
62
                mismatch_file = "/tmp/DoaPickupMismatch.csv"
63
                print "Some of our DOA orders were not picked up. Printing report to:" + mismatch_file
4783 phani.kuma 64
                print_dao_return_pickup_mismatch_report(mismatch_file, doas_not_picked_up)
4559 phani.kuma 65
                pickup_mismatch_part = [get_attachment_part(mismatch_file)]
66
                mail(from_user, from_pwd, to,\
67
                     "DOA Pickup Mismatch for " + provider.name,\
68
                     "This is a system generated email.Please don't reply to it.",\
69
                     pickup_mismatch_part)
70
        except Exception:
71
            print "Some issue sending the DOA mismatch report"
72
            traceback.print_exc()
73
    except:
74
        print "Some issue while processing the orders in DOA_PICKUP_CONFIRMED status"
4506 phani.kuma 75
        traceback.print_exc()
76
 
4741 phani.kuma 77
def process_return_pickup_orders(provider):
78
    try:
79
        returns_tobe_picked_up = fetch_data(provider.id, OrderStatus.RET_PICKUP_CONFIRMED)
80
        returns_pickup_details = read_dao_return_pickup_orders(returns_tobe_picked_up)
81
        returns_not_picked_up = update_picked_returns(provider.id, returns_pickup_details)
82
        try:
83
            if returns_not_picked_up:
84
                print "Return Orders not Picked up:"
85
                print returns_not_picked_up
86
                mismatch_file = "/tmp/ReturnsPickupMismatch.csv"
87
                print "Some of our Return orders were not picked up. Printing report to:" + mismatch_file
4783 phani.kuma 88
                print_dao_return_pickup_mismatch_report(mismatch_file, returns_not_picked_up)
4741 phani.kuma 89
                pickup_mismatch_part = [get_attachment_part(mismatch_file)]
90
                mail(from_user, from_pwd, to,\
91
                     "Return orders Pickup Mismatch for " + provider.name,\
92
                     "This is a system generated email.Please don't reply to it.",\
93
                     pickup_mismatch_part)
94
        except Exception:
95
            print "Some issue sending the Return orders mismatch report"
96
            traceback.print_exc()
97
    except:
98
        print "Some issue while processing the orders in RET_PICKUP_CONFIRMED status"
99
        traceback.print_exc()
100
 
4506 phani.kuma 101
def process_pickup_records(provider):
102
    try:
4559 phani.kuma 103
        orders_tobe_picked_up = fetch_data(provider.id, OrderStatus.SHIPPED_FROM_WH)
104
        pickup_details = read_pickup_orders(orders_tobe_picked_up)
105
        orders_not_picked_up = update_picked_orders(provider.id, pickup_details)
106
        try:
107
            if orders_not_picked_up:
108
                print "Orders not Picked up:"
109
                print orders_not_picked_up
110
                mismatch_file = "/tmp/PickupMismatch.csv"
111
                print "Some of our orders were not picked up. Printing report to:" + mismatch_file
112
                print_pickup_mismatch_report(mismatch_file, orders_not_picked_up)
113
                pickup_mismatch_part = [get_attachment_part(mismatch_file)]
114
                mail(from_user, from_pwd, to,\
115
                     "Order Pickup Mismatch for " + provider.name,\
116
                     "This is a system generated email.Please don't reply to it.",\
117
                     pickup_mismatch_part)
118
        except Exception:
119
            print "Some issue sending the pickup mismatch report"
120
            traceback.print_exc()
121
    except:
122
        print "Some issue while processing the orders in SHIPPED_FROM_WH status"
4506 phani.kuma 123
        traceback.print_exc()
124
 
125
def process_delivery_report(provider):
126
    try:
127
        orders_tobe_delivered = fetch_data(provider.id, OrderStatus.SHIPPED_TO_LOGST)
4540 phani.kuma 128
        delivered_orders, delivered_orders_but_wrong_code_mentioned, returned_orders, undelivered_orders = read_delivery_orders(orders_tobe_delivered)
4506 phani.kuma 129
        if delivered_orders:
130
            update_delivered_orders(provider.id, delivered_orders)
131
        if returned_orders:
132
            update_returned_orders(provider.id, returned_orders)
133
            try:
134
                returned_orders_file = "/tmp/ReturnedOrders.csv"
135
                print_rto_orders_report(returned_orders_file, returned_orders)
136
                returned_orders_report = [get_attachment_part(returned_orders_file)]
137
                mail(from_user, from_pwd, to,\
138
                     "Returned Orders Report for " + provider.name,\
139
                     "This is a system generated email.Please don't reply to it.",\
140
                     returned_orders_report)
141
            except:
142
                print "Some issue sending the returned orders report"
143
                traceback.print_exc()
4540 phani.kuma 144
        if delivered_orders_but_wrong_code_mentioned:
145
            try:
146
                delivered_orders_but_wrong_code_mentioned_file = "/tmp/delivered_orders_but_wrong_code.csv"
147
                print_delivered_orders_but_wrong_code_mentioned_report(delivered_orders_but_wrong_code_mentioned_file, delivered_orders_but_wrong_code_mentioned)
148
                delivered_orders_but_wrong_code_mentioned_report = [get_attachment_part(delivered_orders_but_wrong_code_mentioned_file)]
149
                mail(from_user, from_pwd, to,\
150
                     "Delivered Orders but Wrong Code Mentioned Report for " + provider.name,\
151
                     "This is a system generated email.Please don't reply to it.",\
152
                     delivered_orders_but_wrong_code_mentioned_report)
153
            except:
154
                print "Some issue sending the delivered orders but wrong code mentioned report"
4581 phani.kuma 155
                traceback.print_exc()
156
        try:
157
            orders_not_delivered = update_reason_of_undelivered_orders(provider.id, undelivered_orders)
158
            if orders_not_delivered:
159
                print "Undelivered Orders:"
160
                print orders_not_delivered
161
                mismatch_file = "/tmp/UndeliveredOrders.csv"
162
                print "Some of our Orders were not delivered. Printing report to:" + mismatch_file
163
                print_undelivered_orders_report(mismatch_file, orders_not_delivered)
164
                pickup_mismatch_part = [get_attachment_part(mismatch_file)]
165
                mail(from_user, from_pwd, to,\
166
                     "Orders that are undelivered but picked up or shipped four days ago for " + provider.name,\
167
                     "This is a system generated email.Please don't reply to it.",\
168
                     pickup_mismatch_part)
169
        except Exception:
170
            print "Some issue updating and sending the undelivered orders report"
171
            traceback.print_exc()
4506 phani.kuma 172
    except:
4540 phani.kuma 173
        print "Some issue while processing the orders in SHIPPED_TO_LOGST status"
4506 phani.kuma 174
        traceback.print_exc()
175
 
176
def get_provider_by_name(provider_name):
177
    logistics_client = LogisticsClient().get_client()
178
    provider = None
179
    providers = logistics_client.getAllProviders()
180
    for p in providers:
181
        if p.name == provider_name:
182
            provider=p
183
            break
184
    if provider == None:
185
        sys.exit("Can't continue execution: No such provider")
186
    return provider
187
 
188
def fetch_data(provider_id, order_status):
189
    txnClient = TransactionClient().get_client()
190
    try:
191
        doas_tobe_picked_up = txnClient.getOrdersForProviderForStatus(provider_id, order_status)
192
        return doas_tobe_picked_up
193
    except TransactionServiceException as tex:
194
        print tex.message
195
 
4741 phani.kuma 196
def read_dao_return_pickup_orders(orders_tobe_picked_up):
4506 phani.kuma 197
    #uri=http://www.aramex.com/track_xml.asp?ShipperRef=61582&OrgCntry=In&FromDate=2-6-2012&ToDate=2-6-2012
4741 phani.kuma 198
    picked_up_orders = {}
199
    for order in orders_tobe_picked_up:
4506 phani.kuma 200
        try:
4741 phani.kuma 201
            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")
202
            root = parse(urllib2.urlopen(uri)).getroot()
4506 phani.kuma 203
            nodes = root.findall('HAWBDetails/HAWBHistory/HAWBUpdate')
204
            if len(nodes):
205
                element = nodes[len(nodes)-1]
4540 phani.kuma 206
                if element.findtext('Status', '') == 'SHOR' and element.findtext('Condition', '') == 'PKUP':
4506 phani.kuma 207
                    delivery_date = get_py_datetime(element.findtext('ActionDate', ''))
4741 phani.kuma 208
                    picked_up_orders[order.pickupRequestNo] = str(delivery_date)
4506 phani.kuma 209
        except:
210
            pass
211
 
4741 phani.kuma 212
    print "Picked up Orders:"
213
    print picked_up_orders
214
    return picked_up_orders
4506 phani.kuma 215
 
216
def read_pickup_orders(orders_tobe_picked_up):
217
    try:
218
        config_client = ConfigClient()
219
        ARAMEX_URL = config_client.get_property("aramex_update_url")
220
    except ConfigException as cex:
221
        print cex.message
222
        traceback.print_exc()
223
 
224
    picked_up_orders = {}
225
    for order in orders_tobe_picked_up:
226
        try:
4741 phani.kuma 227
            uri = ARAMEX_URL + order.airwaybill_no
228
            root = parse(urllib2.urlopen(uri)).getroot()
4506 phani.kuma 229
            nodes = root.findall('HAWBDetails/HAWBHistory/HAWBUpdate')
230
            if len(nodes):
231
                element = nodes[len(nodes)-1]
4540 phani.kuma 232
                if element.findtext('Status', '') == 'SHOR' and element.findtext('Condition', '') == 'PKUP':
4506 phani.kuma 233
                    delivery_date = get_py_datetime(element.findtext('ActionDate', ''))
234
                    picked_up_orders[order.airwaybill_no] = str(delivery_date)
235
        except:
236
            pass
237
 
238
    print "Picked up Orders:"
239
    print picked_up_orders
240
    return picked_up_orders
241
 
242
def read_delivery_orders(orders_tobe_delivered):
243
    try:
244
        config_client = ConfigClient()
245
        ARAMEX_URL = config_client.get_property("aramex_update_url")
246
    except ConfigException as cex:
247
        print cex.message
248
        traceback.print_exc()
249
 
250
    delivered_orders = {}
4540 phani.kuma 251
    delivered_orders_but_wrong_code_mentioned = {}
4506 phani.kuma 252
    returned_orders = {}
253
    undelivered_orders = {}
254
    for order in orders_tobe_delivered:
255
        try:
4741 phani.kuma 256
            uri = ARAMEX_URL + order.airwaybill_no
257
            root = parse(urllib2.urlopen(uri)).getroot()
4506 phani.kuma 258
            nodes = root.findall('HAWBDetails/HAWBHistory/HAWBUpdate')
259
            if len(nodes):
260
                i = len(nodes)-1
261
                while i>=0:
262
                    element = nodes[i]
4540 phani.kuma 263
                    if element.findtext('Status', '') == 'SHDL' and (element.findtext('Condition', '') == 'DLVD' or element.findtext('Condition', '') == 'DPTT' or element.findtext('Condition', '') == 'DLPT' or element.findtext('Condition', '') == 'LTRB'):
4506 phani.kuma 264
                        delivery_date = get_py_datetime(element.findtext('ActionDate', ''))
265
                        receiver = root.findtext('HAWBDetails/DeliveredTo', '')
266
                        delivered_orders[order.airwaybill_no] = str(delivery_date) + "|" +  receiver
4540 phani.kuma 267
                        if element.findtext('Condition', '') != 'DLVD':
268
                            delivered_orders_but_wrong_code_mentioned[order.airwaybill_no] = element.findtext('Condition', '')
4506 phani.kuma 269
                        break
4540 phani.kuma 270
                    elif element.findtext('Condition', '') == 'RTRN' and (element.findtext('Status', '') == 'SHRH' or element.findtext('Status', '') == 'SHUP'):
4506 phani.kuma 271
                        delivery_date = get_py_datetime(element.findtext('ActionDate', ''))
272
                        if i < len(nodes)-1:
273
                            reason_for_return = nodes[i+1].findtext('CustomerDescription', '')
274
                        else:
275
                            reason_for_return = element.findtext('CustomerDescription', '')
276
                        returned_orders[order.airwaybill_no] = str(delivery_date) + "|" + reason_for_return
277
                        break
278
                    elif i == 0:
4760 phani.kuma 279
                        reason = root.findtext('HAWBDetails/CurrentStatus', '')
4506 phani.kuma 280
                        undelivered_orders[order.airwaybill_no] = reason
281
                        break
282
                    i = i-1
283
        except:
284
            pass
285
 
286
    print "Delivered Orders:"
287
    print delivered_orders
288
 
4540 phani.kuma 289
    print "Delivered Orders but wrong code mentioned:"
290
    print delivered_orders_but_wrong_code_mentioned
291
 
4506 phani.kuma 292
    print "Returned Orders:"
293
    print returned_orders
294
 
295
    print "Undelivered Orders"
296
    print undelivered_orders
297
 
4540 phani.kuma 298
    return delivered_orders, delivered_orders_but_wrong_code_mentioned, returned_orders, undelivered_orders
4506 phani.kuma 299
 
300
def update_picked_orders(provider_id, pickup_details):
301
    txnClient = TransactionClient().get_client()
302
    try:
303
        orders_not_picked_up = txnClient.markOrdersAsPickedUp(provider_id, pickup_details)
304
        return orders_not_picked_up
305
    except TransactionServiceException as tex:
306
        print tex.message
307
 
308
def update_picked_doas(provider_id, doa_pickup_details):
309
    txnClient = TransactionClient().get_client()
310
    try:
311
        doas_not_picked_up = txnClient.markDoasAsPickedUp(provider_id, doa_pickup_details)
312
        return doas_not_picked_up
313
    except TransactionServiceException as tex:
314
        print tex.message
315
 
4741 phani.kuma 316
def update_picked_returns(provider_id, returns_pickup_details):
317
    txnClient = TransactionClient().get_client()
318
    try:
319
        returns_not_picked_up = txnClient.markReturnOrdersAsPickedUp(provider_id, returns_pickup_details)
320
        return returns_not_picked_up
321
    except TransactionServiceException as tex:
322
        print tex.message
323
 
4506 phani.kuma 324
def update_delivered_orders(provider_id, delivered_orders):
325
    txnClient = TransactionClient().get_client()
326
    try:
327
        txnClient.markOrdersAsDelivered(provider_id, delivered_orders)
328
    except TransactionServiceException as tex:
329
        print tex.message
330
 
331
def update_returned_orders(provider_id, returned_orders):
332
    txnClient = TransactionClient().get_client()
333
    try:
334
        txnClient.markOrdersAsFailed(provider_id, returned_orders)
335
    except TransactionServiceException as tex:
336
        print tex.message
337
 
338
def update_reason_of_undelivered_orders(provider_id, undelivered_orders):
339
    txnClient = TransactionClient().get_client()
340
    try:
4581 phani.kuma 341
        orders_not_delivered = txnClient.updateNonDeliveryReason(provider_id, undelivered_orders)
342
        return orders_not_delivered
4506 phani.kuma 343
    except TransactionServiceException as tex:
344
        print tex.message
345
 
346
def print_pickup_mismatch_report(filename, orders):
347
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
348
    writer.writerow(['Order Id', 'AWB No', 'Shipping timestamp'])
349
    for order in orders:
350
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.shipping_timestamp)])
351
 
4783 phani.kuma 352
def print_dao_return_pickup_mismatch_report(filename, orders):
353
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
354
    writer.writerow(['Order Id', 'Pickup Request No', 'Authorization timestamp'])
355
    for order in orders:
356
        writer.writerow([order.id, order.pickupRequestNo, to_py_date(order.doa_auth_timestamp)])
357
 
4506 phani.kuma 358
def print_rto_orders_report(filename, returned_orders):
359
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
360
    writer.writerow(['AWB No', 'Return date', 'Reason'])
361
    for awb, date_reason in returned_orders.iteritems():
362
        date, reason = date_reason.split('|')
4792 phani.kuma 363
        if reason is not None:
364
            reason = reason.replace(","," ")
4506 phani.kuma 365
        writer.writerow([awb, date, reason])
366
 
4540 phani.kuma 367
def print_delivered_orders_but_wrong_code_mentioned_report(filename, delivered_orders_but_wrong_code_mentioned):
368
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
369
    writer.writerow(['AWB No', 'Code Used'])
370
    for awb, code_used in delivered_orders_but_wrong_code_mentioned.iteritems():
371
        writer.writerow([awb, code_used])
372
 
4581 phani.kuma 373
def print_undelivered_orders_report(filename, orders):
374
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
375
    writer.writerow(['Order Id', 'AWB No', 'Status', 'Status Description', 'Shipping timestamp', 'Pickup timestamp'])
376
    for order in orders:
4792 phani.kuma 377
        statusDescription = ''
378
        if order.statusDescription is not None:
379
            statusDescription = order.statusDescription.replace(","," ")
380
        writer.writerow([order.id, order.airwaybill_no, order.status, statusDescription, to_py_date(order.shipping_timestamp), to_py_date(order.pickup_timestamp)])
4581 phani.kuma 381
 
4506 phani.kuma 382
def get_py_datetime(time_string):
383
    # This should be a command line argument.
384
    # Refer http://docs.python.org/library/time.html#time.strftime to
385
    # get a complete list of format specifiers available for date time.
386
    time_format = "%m/%d/%Y %I:%M:%S %p"
387
    if time_string == '':
388
        return None
389
    mytime = time.strptime(time_string, time_format)
390
    return datetime.datetime(*mytime[:6])
391
 
392
def main():
393
    parser = optparse.OptionParser()
394
    parser.add_option("-p", "--pickup", dest="pickup_report",
395
                   action="store_true",
396
                   help="Run the pickup reconciliation")
397
    parser.add_option("-d", "--delivery", dest="delivery_report",
398
                   action="store_true",
399
                   help="Run the delivery reconciliation")
400
    parser.add_option("-a", "--all", dest="all_reports",
401
                   action="store_true",
402
                   help="Run all reconciliations")
403
    parser.add_option("-P", "--provider", dest="provider",
4508 phani.kuma 404
                   default="Aramex", type="string",
4506 phani.kuma 405
                   help="The PROVIDER this report is for",
406
                   metavar="PROVIDER")
4741 phani.kuma 407
    parser.set_defaults(pickup_report=False, delivery_report=False, all_reports=False)
4506 phani.kuma 408
    (options, args) = parser.parse_args()
409
    if len(args) != 0:
410
        parser.error("You've supplied extra arguments. Are you sure you want to run this program?")
411
 
412
    if options.all_reports:
413
        options.pickup_report = True
414
        options.delivery_report = True
415
 
416
    provider = get_provider_by_name(options.provider)
417
 
418
    if options.pickup_report:
419
        process_pickup_records(provider)
4815 phani.kuma 420
        process_dao_pickup_orders(provider)
421
        process_return_pickup_orders(provider)
4506 phani.kuma 422
    if options.delivery_report:
423
        process_delivery_report(provider)
424
 
425
if __name__ == '__main__':
426
    main()