Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
3476 chandransh 1
#!/usr/bin/python
1132 chandransh 2
 
1246 chandransh 3
import time
1132 chandransh 4
import datetime
5
import optparse
6
import sys
7
import csv
8
import xlrd
3476 chandransh 9
import traceback
1132 chandransh 10
 
11
if __name__ == '__main__' and __package__ is None:
12
    import os
13
    sys.path.insert(0, os.getcwd())
14
 
15
from shop2020.clients.LogisticsClient import LogisticsClient
16
from shop2020.clients.TransactionClient import TransactionClient
17
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException
18
from shop2020.utils.EmailAttachmentDownloader import download_attachment
1246 chandransh 19
from shop2020.utils.EmailAttachmentSender import get_attachment_part, mail
1132 chandransh 20
from shop2020.utils.Utils import to_py_date
21
 
1246 chandransh 22
from_user = 'cnc.center@shop2020.in'
23
from_pwd = '5h0p2o2o'
3475 chandransh 24
to = ['cnc.center@shop2020.in']
1246 chandransh 25
 
1132 chandransh 26
def process_pickup_records(provider):
2001 chandransh 27
    try:
28
        filename = fetch_report(provider.name.upper() + ' PICKUP REPORT')
2764 chandransh 29
        pickup_details, doa_pickup_details = read_pickup_report(filename)
2001 chandransh 30
        orders_not_picked_up = update_picked_orders(provider.id, pickup_details)
2764 chandransh 31
        try:
32
            if orders_not_picked_up:
3476 chandransh 33
                mismatch_file = "/tmp/PickupMismatch.csv"
2764 chandransh 34
                print "Some of our orders were not picked up. Printing report to:" + mismatch_file
35
                print_pickup_mismatch_report(mismatch_file, orders_not_picked_up)
3476 chandransh 36
                pickup_mismatch_part = [get_attachment_part(mismatch_file)]
2764 chandransh 37
                mail(from_user, from_pwd, to,\
38
                     "Order Pickup Mismatch for " + provider.name,\
39
                     "This is a system generated email.Please don't reply to it.",\
40
                     pickup_mismatch_part)
41
        except Exception:
42
            print "Some issue sending the mismatch report"
3476 chandransh 43
            traceback.print_exc()
2764 chandransh 44
 
45
        doas_not_picked_up = update_picked_doas(provider.id, doa_pickup_details)
46
        try:
47
            if doas_not_picked_up:
3476 chandransh 48
                mismatch_file = "/tmp/DoaPickupMismatch.csv"
2764 chandransh 49
                print "Some of our DOA orders were not picked up. Printing report to:" + mismatch_file
50
                print_pickup_mismatch_report(mismatch_file, doas_not_picked_up)
3475 chandransh 51
                pickup_mismatch_part = [get_attachment_part(mismatch_file)]
2764 chandransh 52
                mail(from_user, from_pwd, to,\
53
                     "DOA Pickup Mismatch for " + provider.name,\
54
                     "This is a system generated email.Please don't reply to it.",\
55
                     pickup_mismatch_part)
56
        except Exception:
57
            print "Some issue sending the mismatch report"
3476 chandransh 58
            traceback.print_exc()
2001 chandransh 59
    finally:
60
        os.remove(filename)
1132 chandransh 61
 
62
def process_delivery_report(provider):
2001 chandransh 63
    try:
64
        filename = fetch_report(provider.name.upper() + ' DELIVERED AND RTO REPORT')
65
        #filename = 'delivery_report.xls'
66
        delivered_orders, returned_orders = read_delivery_report(filename)
67
        if delivered_orders:
68
            update_delivered_orders(provider.id, delivered_orders)
69
        if returned_orders:
70
            update_returned_orders(provider.id, returned_orders)
71
 
72
            mail(from_user, from_pwd, to,\
73
                 "Returned Orders Report for " + provider.name,\
74
                 "This is a system generated email.Please don't reply to it.",\
3475 chandransh 75
                 [])
3476 chandransh 76
    except:
77
        print "Some issue sending the returned orders report"
78
        traceback.print_exc()
2001 chandransh 79
    finally:
80
        os.remove(filename)
1132 chandransh 81
 
82
def process_non_delivery_report(provider):
2001 chandransh 83
    try:
84
        filename = fetch_report(provider.name.upper() + ' UNDELIVERED REPORT')
85
        undelivered_orders = read_undelivered_report(filename)
86
        update_reason_of_undelivered_orders(provider.id, undelivered_orders)
87
    finally:
88
        os.remove(filename)
1246 chandransh 89
 
90
def update_reason_of_undelivered_orders(provider_id, undelivered_orders):
91
    txnClient = TransactionClient().get_client()
92
    try:
93
        txnClient.updateNonDeliveryReason(provider_id, undelivered_orders)
94
    except TransactionServiceException as tex:
95
        print tex.message
96
 
1132 chandransh 97
def get_provider_by_name(provider_name):
98
    logistics_client = LogisticsClient().get_client()
1246 chandransh 99
    #TODO: Write a thrift call to get a provider by name
1132 chandransh 100
    provider = None
101
    providers = logistics_client.getAllProviders()
102
    for p in providers:
103
        if p.name == provider_name:
104
            provider=p
105
            break
106
    if provider == None:
107
        sys.exit("Can't continue execution: No such provider")
108
    return provider
109
 
110
def fetch_report(type):
111
    filename = download_attachment(type, todays_date_string())
112
    if filename is None:
113
        sys.exit("The " + type + " report is not yet available.")
114
    return filename
115
 
116
def read_pickup_report(filename):
117
    print "Reading pickup report from:" + filename
118
    workbook = xlrd.open_workbook(filename)
119
    sheet = workbook.sheet_by_index(0)
120
    num_rows = sheet.nrows
121
    picked_up_orders = {}
2764 chandransh 122
    picked_up_doas = {}
1132 chandransh 123
    for rownum in range(1, num_rows):
2764 chandransh 124
        unused_customer_code, awb, ref_no, timeval, date = sheet.row_values(rownum)[0:5]
1263 chandransh 125
        picked_up_orders[awb] = str(get_py_datetime(date, timeval))
2764 chandransh 126
        picked_up_doas[ref_no] = str(get_py_datetime(date, timeval))
1135 chandransh 127
 
128
    print "Picked up Orders:"
129
    print picked_up_orders
2764 chandransh 130
    print picked_up_doas
131
    return picked_up_orders, picked_up_doas
1132 chandransh 132
 
133
def read_delivery_report(filename):
134
    print "Reading delivery details from:" + filename
135
    workbook = xlrd.open_workbook(filename)
136
    sheet = workbook.sheet_by_index(0)
137
    num_rows = sheet.nrows
138
    delivered_orders = {}
139
    returned_orders = {}
140
    for rownum in range(1, num_rows):
2625 chandransh 141
        unused_customer_code, awb, unused_ref_no, timeval, date, unused_status, receiver, reason_for_return = sheet.row_values(rownum)[0:8]
1265 chandransh 142
        delivery_date = str(get_py_datetime(date, timeval))
1132 chandransh 143
        if receiver: #TODO: Use status for this check
1246 chandransh 144
            delivered_orders[awb] = delivery_date + "|" +  receiver
1132 chandransh 145
        else:
1246 chandransh 146
            returned_orders[awb] = delivery_date + "|" + reason_for_return
1135 chandransh 147
 
1132 chandransh 148
    print "Delivered Orders:"
149
    print delivered_orders
150
 
151
    print "Returned Orders:"
152
    print returned_orders
153
    return delivered_orders, returned_orders
154
 
1246 chandransh 155
def read_undelivered_report(filename):
156
    print "Reading undelivered details from:" + filename
157
    workbook = xlrd.open_workbook(filename)
158
    sheet = workbook.sheet_by_index(0)
159
    num_rows = sheet.nrows
160
    undelivered_orders = {}
161
    for rownum in range(1, num_rows):
2625 chandransh 162
        unused_cusotmer_code, awb, unused_ref_no, reason, timeval, date = sheet.row_values(rownum)[0:6]
2001 chandransh 163
        try:
164
            unused_status_date = str(get_py_datetime(date, timeval))
165
        except ValueError:
166
            #ValueError can be expected if the date or time are not in the expected format
167
            #Harmless error for now since we are not storing the status date
168
            print sys.exc_info()[0]
1246 chandransh 169
        undelivered_orders[awb] = reason
170
 
171
    print "Undelivered Orders"
172
    print undelivered_orders
173
 
174
    return undelivered_orders
175
 
1132 chandransh 176
def update_picked_orders(provider_id, pickup_details):
177
    txnClient = TransactionClient().get_client()
178
    try:
179
        orders_not_picked_up = txnClient.markOrdersAsPickedUp(provider_id, pickup_details)
180
        return orders_not_picked_up
181
    except TransactionServiceException as tex:
182
        print tex.message
183
 
2764 chandransh 184
def update_picked_doas(provider_id, doa_pickup_details):
185
    txnClient = TransactionClient().get_client()
186
    try:
187
        doas_not_picked_up = txnClient.markDoasAsPickedUp(provider_id, doa_pickup_details)
188
        return doas_not_picked_up
189
    except TransactionServiceException as tex:
190
        print tex.message
191
 
1135 chandransh 192
def update_delivered_orders(provider_id, delivered_orders):
1132 chandransh 193
    txnClient = TransactionClient().get_client()
194
    try:
1135 chandransh 195
        txnClient.markOrdersAsDelivered(provider_id, delivered_orders)
1132 chandransh 196
    except TransactionServiceException as tex:
197
        print tex.message
198
 
1135 chandransh 199
def update_returned_orders(provider_id, returned_orders):
200
    txnClient = TransactionClient().get_client()
201
    try:
202
        txnClient.markOrdersAsFailed(provider_id, returned_orders)
203
    except TransactionServiceException as tex:
204
        print tex.message
1132 chandransh 205
 
1246 chandransh 206
def print_pickup_mismatch_report(filename, orders):
1132 chandransh 207
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
208
    writer.writerow(['Order Id', 'AWB No', 'Shipping timestamp'])
209
    for order in orders:
210
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.shipping_timestamp)])
211
 
212
def todays_date_string():
1246 chandransh 213
    today_date = time.strftime("%d-%b-%Y")
214
    return '"' + today_date + '"'
1132 chandransh 215
 
1263 chandransh 216
def get_py_datetime(date, timeval):
1246 chandransh 217
    # This should be a command line argument.
218
    # Refer http://docs.python.org/library/time.html#time.strftime to
219
    # get a complete list of format specifiers available for date time.
220
    time_format = "%d-%b-%y %H%M"
2693 chandransh 221
    if timeval is None or timeval == '--':
222
        timeval='0000'
1263 chandransh 223
    time_string = date + " " + timeval
1246 chandransh 224
    mytime = time.strptime(time_string, time_format)
225
    return datetime.datetime(*mytime[:6])
226
 
1132 chandransh 227
def main():
228
    parser = optparse.OptionParser()
229
    parser.add_option("-p", "--pickup", dest="pickup_report",
230
                   action="store_true",
231
                   help="Run the pickup reconciliation")
232
    parser.add_option("-d", "--delivery", dest="delivery_report",
233
                   action="store_true",
234
                   help="Run the delivery reconciliation")
235
    parser.add_option("-n", "--non-delivery", dest="non_delivery_report",
236
                   action="store_true",
237
                   help="Run the non delivery reconciliation")
238
    parser.add_option("-a", "--all", dest="all_reports",
239
                   action="store_true",
240
                   help="Run all reconciliations")
241
    parser.add_option("-P", "--provider", dest="provider",
242
                   default="BlueDart", type="string",
243
                   help="The PROVIDER this report is for",
244
                   metavar="PROVIDER")
245
    parser.set_defaults(pickup_report=False, delivery_report=False, non_delivery_report=False, all_reports=False)
246
    (options, args) = parser.parse_args()
247
    if len(args) != 0:
248
        parser.error("You've supplied extra arguments. Are you sure you want to run this program?")
249
 
250
    if options.all_reports:
251
        options.pickup_report = True
252
        options.delivery_report = True
253
        options.non_delivery_report = True
254
 
255
    provider = get_provider_by_name(options.provider)
256
 
257
    if options.pickup_report:
258
        process_pickup_records(provider)
259
    if options.delivery_report:
260
        process_delivery_report(provider)
261
    if options.non_delivery_report:
262
        process_non_delivery_report(provider)
263
 
264
if __name__ == '__main__':
1718 chandransh 265
    main()