Subversion Repositories SmartDukaan

Rev

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