Subversion Repositories SmartDukaan

Rev

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

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