Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
104 ashish 1
'''
2
Created on 29-Mar-2010
3
 
4
@author: ashish
5
'''
1262 varun.gupt 6
from string import Template
7
from email.mime.multipart import MIMEMultipart
8
from shop2020.thriftpy.utils.ttypes import HelperServiceException, Mail
9
from email.mime.base import MIMEBase
10
from email import encoders
11
from email.mime.text import MIMEText
12
import os
13
import smtplib
14
import time
15
from time import strftime
16
 
104 ashish 17
from shop2020.model.v1.order.impl.DataService import Transaction, LineItem,\
1225 chandransh 18
    Alerts, Order, BatchNoGenerator
104 ashish 19
from shop2020.thriftpy.model.v1.order.ttypes import Transaction as T_Transaction,\
690 chandransh 20
    TransactionServiceException, TransactionStatus, OrderStatus
104 ashish 21
import datetime
122 ashish 22
from elixir import *
855 rajveer 23
from shop2020.utils.Utils import to_py_date, to_java_date
104 ashish 24
from sqlalchemy.sql.expression import and_
483 rajveer 25
from shop2020.model.v1 import order
743 rajveer 26
from shop2020.clients.LogisticsClient import LogisticsClient
871 chandransh 27
from shop2020.clients.InventoryClient import InventoryClient
1262 varun.gupt 28
from shop2020.clients.UserClient import UserClient
1351 varun.gupt 29
from shop2020.clients.HelperClient import HelperClient
104 ashish 30
 
31
def get_new_transaction():
32
    transaction = Transaction()
33
    transaction.createdOn = datetime.datetime.now()
738 chandransh 34
    transaction.status = TransactionStatus.INIT
104 ashish 35
    transaction.status_message = "New transaction"
483 rajveer 36
    return transaction
37
 
38
def create_order(t_order):
39
    order = Order()
40
    if t_order.warehouse_id:
41
        order.warehouse_id = t_order.warehouse_id
509 rajveer 42
    if t_order.logistics_provider_id:    
483 rajveer 43
        order.logistics_provider_id = t_order.logistics_provider_id
44
        order.airwaybill_no = t_order.airwaybill_no
45
        order.tracking_id = t_order.tracking_id
46
    if t_order.expected_delivery_time:    
47
        order.expected_delivery_time = to_py_date(t_order.expected_delivery_time)
48
    if t_order.customer_id:    
49
        order.customer_id = t_order.customer_id
50
        order.customer_name = t_order.customer_name
860 rajveer 51
        order.customer_city = t_order.customer_city
52
        order.customer_state = t_order.customer_state
483 rajveer 53
        order.customer_mobilenumber = t_order.customer_mobilenumber
54
        order.customer_pincode = t_order.customer_pincode
738 chandransh 55
        order.customer_address1 = t_order.customer_address1
56
        order.customer_address2 = t_order.customer_address2
483 rajveer 57
        order.customer_email = t_order.customer_email
58
    #new status and status description to be added    
716 rajveer 59
    order.status = t_order.status  
483 rajveer 60
    order.statusDescription = t_order.statusDescription
61
    order.total_amount = t_order.total_amount
62
    order.total_weight = t_order.total_weight
63
    if t_order.created_timestamp:
64
        order.created_timestamp = to_py_date(t_order.created_timestamp)
65
    else:
685 chandransh 66
        order.created_timestamp = datetime.datetime.now()
483 rajveer 67
    return order
68
 
69
def create_transaction(t_transaction):
70
    t_orders = t_transaction.orders
71
    if not t_orders:
72
        raise TransactionServiceException(101, "Orders missing from the transaction")
73
    transaction = get_new_transaction()
74
    transaction.customer_id = t_transaction.customer_id 
75
    transaction.shopping_cart_id = t_transaction.shoppingCartid
76
 
77
    for t_order in t_orders:
78
        order = create_order(t_order)
79
        order.transaction = transaction 
80
        for line_item in t_order.lineitems:
81
            litem = LineItem()
716 rajveer 82
            litem.item_id = line_item.item_id
963 chandransh 83
            litem.productGroup = line_item.productGroup
483 rajveer 84
            litem.brand = line_item.brand
85
            if line_item.model_number:
86
                litem.model_number = line_item.model_number
87
            if line_item.model_name:    
88
                litem.model_name = line_item.model_name
908 chandransh 89
            if line_item.color:
90
                litem.color = line_item.color
483 rajveer 91
            if line_item.extra_info:
92
                litem.extra_info = line_item.extra_info
93
            litem.quantity = line_item.quantity
94
            litem.unit_price = line_item.unit_price
95
            litem.unit_weight = line_item.unit_weight
96
            litem.total_price = line_item.total_price
97
            litem.total_weight = line_item.total_weight
1262 varun.gupt 98
            litem.transfer_price = line_item.transfer_price
483 rajveer 99
            """
100
            if line_item.addedOn:
101
                litem.added_on = to_py_date(line_item.addedOn)
102
            else:
103
                litem.added_on = datetime.datetime.now()
104
            """
105
            litem.order = order
106
    session.commit()
107
    return transaction.id
108
 
109
def get_transaction(transaction_id):
110
    transaction = Transaction.get_by(id=transaction_id)
111
    if not transaction:
112
        raise TransactionServiceException(108, "no such transaction")
113
 
114
    return transaction
115
 
116
def get_transactions_for_customer(customer_id, from_date, to_date, status):
117
    if not customer_id:
118
        raise TransactionServiceException(101, "bad customer id")
119
    query = Transaction.query.filter(Transaction.customer_id == customer_id)
120
    if status:
121
        query = query.filter(Transaction.status == status)
122
    if from_date:
123
        query = query.filter(Transaction.createdOn >from_date)
124
    if to_date:
125
        query = query.filter(Transaction.createdOn < to_date)
126
    return query.all()
127
 
128
def get_transactions_for_shopping_cart_id(shopping_cart_id):
129
    transactions = Transaction.query.filter_by(shopping_cart_id=shopping_cart_id).all()
130
    if not transactions:
131
        raise TransactionServiceException(108, "transactions for this shopping cart")
132
    return transactions
133
 
134
def get_transaction_status(transaction_id):
135
    if not transaction_id:
136
        raise TransactionServiceException(101, "bad transaction id")
137
 
138
    transaction = get_transaction(transaction_id)
139
 
140
    return transaction.status
141
 
142
def change_transaction_status(transaction_id, new_status, description):
143
    transaction = get_transaction(transaction_id)
144
    transaction.status = new_status
145
    transaction.status_message = description
690 chandransh 146
    if new_status == TransactionStatus.FAILED:
147
        for order in transaction.orders:
148
            order.status = OrderStatus.PAYMENT_FAILED
149
    elif new_status == TransactionStatus.IN_PROCESS:
150
        for order in transaction.orders:
151
            order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
1219 chandransh 152
            order.statusDescription = "Submitted to warehouse"
743 rajveer 153
            #After we got payment success, we will set logistics info also 
154
            logistics_client = LogisticsClient().get_client()
155
            #FIXME line item is only one now. If multiple will come, need to fix.
871 chandransh 156
            item_id = order.lineitems[0].item_id
157
            logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id)
743 rajveer 158
 
159
            order.warehouse_id = logistics_info.warehouseId
160
            order.logistics_provider_id = logistics_info.providerId
161
            order.airwaybill_no = logistics_info.airway_billno
162
            order.tracking_id = order.airwaybill_no
855 rajveer 163
            order.expected_delivery_time = datetime.datetime.now() + datetime.timedelta(days=logistics_info.deliveryTime)
871 chandransh 164
 
165
            catalog_client = InventoryClient().get_client()
166
            catalog_client.reserveItemInWarehouse(item_id, logistics_info.warehouseId, order.lineitems[0].quantity)
1351 varun.gupt 167
 
1341 chandransh 168
            item_pricing = catalog_client.getItemPricing(item_id, order.warehouse_id)
169
            order.lineitems[0].transfer_price = item_pricing.transferPrice
1262 varun.gupt 170
 
1276 chandransh 171
        try:
172
            #Email the information of order placed to customer
173
            email_transaction_info_to_user(transaction_id)
174
        except Exception as ex:
175
            #Nothing much to do. Customer will not know that there was a transaction.
176
            print ex
483 rajveer 177
    session.commit()
178
    return True
179
 
1262 varun.gupt 180
def email_transaction_info_to_user(transaction_id):
181
    transaction = get_transaction(transaction_id)
182
 
183
    html_header = """
184
<html>
185
<body>
186
<div>
187
    <p>
188
        Hello,<br /><br />
189
        Thanks for your placing your order with us. Following are the details of your order:
190
    </p>
191
    <div>
192
        Order Date: $order_date
193
    </div><hr />
194
    <div>
195
        <b>Order Details</b>
196
        <hr />
197
        <table>
198
        <tr>
199
            <th>Order No.</th>
200
            <th>Product</th>
201
            <th>Quantity</th>
202
            <th>Unit Price</th>
203
            <th>Amount</th>
204
        </tr>
205
    """
206
    total_amount = 0.0
207
    html_table = ""
208
 
209
    for order in transaction.orders:
210
        order_date = order.created_timestamp
211
        html_tr = "<tr><td>" + str(order.id) + "</td>"
212
 
213
        for lineitem in order.lineitems:
1276 chandransh 214
            html_tr += "<td>" + str(lineitem) + "</td>"
1262 varun.gupt 215
            html_tr += "<td>" + str(lineitem.quantity) + "</td>"
216
            html_tr += "<td>" + str(lineitem.unit_price) + "</td>"
217
            html_tr += "<td>" + str(lineitem.total_price) + "</td></tr>"
218
            total_amount += lineitem.total_price
219
            html_table += html_tr
220
    html_footer = """
221
        <tr><td colspan=5>&nbsp;</td></tr>
222
        <tr>
223
            <td colspan=4>Total Amount</td>
224
            <td>$total_amount</td>
225
        </tr>
226
        </table>
227
    </div><hr />
228
    <p>
229
        Best Wishes,<br />
230
        Saholic Team
231
    </p>
232
</div>
233
</body>
234
</html>
235
    """
236
#    formated_order_date = strftime("%B %d, %Y %H:%M %p", time.strptime(order_date, "%Y-%m-%d %H:%M:%S"))
237
    formated_order_date = order_date
238
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date))
239
    email_footer = Template(html_footer).substitute(dict(total_amount = total_amount))
240
 
1351 varun.gupt 241
    try:
242
        user_client = UserClient().get_client()
243
        user = user_client.getUserById(transaction.customer_id)
1262 varun.gupt 244
 
1351 varun.gupt 245
        helper_client = HelperClient().get_client()
246
        mail = Mail(user.email, "Saholic - Order Details", email_header + html_table + email_footer, None, None, None)
247
        helper_client.sendMail(mail)
248
        return True
249
    except Exception as e:
250
        print e
251
        return False
1262 varun.gupt 252
 
483 rajveer 253
def get_order(order_id):
254
    order = Order.get_by(id=order_id)
255
    if not order:
256
        raise TransactionServiceException(108, "no such order")
257
 
258
    return order
259
 
260
def get_orders_for_customer(customer_id, from_date, to_date, status):
261
    if not customer_id:
262
        raise TransactionServiceException(101, "bad customer id")
263
    query = Order.query.filter(Order.customer_id == customer_id)
264
    if status:
265
        query = query.filter(Order.status == status)
266
    if from_date:
267
        query = query.filter(Order.created_timestamp >from_date)
268
    if to_date:
269
        query = query.filter(Order.created_timestamp < to_date)
270
    return query.all()
271
 
272
def get_all_orders(status, from_date, to_date, warehouse_id):
273
    if not warehouse_id:
274
        raise TransactionServiceException(101, "bad warehouse id")
275
    query = Order.query.filter(Order.warehouse_id == warehouse_id)
276
    if status:
277
        query = query.filter(Order.status == status)
278
    if from_date:
279
        query = query.filter(Order.created_timestamp >from_date)
280
    if to_date:
281
        query = query.filter(Order.created_timestamp < to_date)
282
    return query.all()
283
 
995 varun.gupt 284
def get_orders_by_billing_date(status, start_billing_date, end_billing_date, warehouse_id):
285
    if not warehouse_id:
286
        raise TransactionServiceException(101, "bad warehouse id")
287
 
288
    query = Order.query.filter(Order.warehouse_id == warehouse_id)
289
 
290
    if status:
291
        query = query.filter(Order.status == status)
292
 
293
    if start_billing_date:
294
        query = query.filter(Order.billing_timestamp >= start_billing_date)
295
 
296
    if end_billing_date:
297
        query = query.filter(Order.billing_timestamp <= end_billing_date)
298
 
299
    return query.all()
300
 
1208 chandransh 301
def get_orders_for_transaction(transaction_id):
302
    orders = Order.query.filter_by(transaction_id=transaction_id).all()
303
    if not orders:
304
        raise TransactionServiceException(101, "No order for the transaction")
305
    return orders
306
 
307
def get_line_items_for_order(order_id):
308
    query = LineItem.query.filter(LineItem.order_id == order_id)
309
    return query.all()
310
 
483 rajveer 311
def change_order_status(self, orderId, status, description):
312
    order = get_order(orderId)
313
    order.status = status
314
    order.statusDescription = description
315
    session.commit()
316
    return True
317
 
921 rajveer 318
def accept_order(self, orderId):
319
    order = get_order(orderId)
320
    order.status = OrderStatus.ACCEPTED
321
    order.statusDescription = "Order Accepted"
322
    order.accepted_timestamp = datetime.datetime.now()
323
    session.commit()
324
    return True
325
 
326
def bill_order(self, orderId):
327
    order = get_order(orderId)
328
    order.status = OrderStatus.BILLED
329
    order.statusDescription = "Order Billed"
330
    order.billing_timestamp = datetime.datetime.now()
331
    session.commit()
1208 chandransh 332
    return True
921 rajveer 333
 
1149 chandransh 334
def add_billing_details(orderId, invoice_number, billed_by):
494 rajveer 335
    order = Order.get_by(id=orderId)
336
    if not order:
337
        raise TransactionServiceException(101, "No order found for the givem orderid")
338
    order.invoice_number = invoice_number
339
    order.billed_by = billed_by
340
    session.commit()
341
    return True
759 chandransh 342
 
1149 chandransh 343
def add_jacket_number(orderId, jacket_number):
344
    order = Order.get_by(id=orderId)
345
    if not order:
346
        raise TransactionServiceException(101, "No order found for the givem orderid")
347
    order.jacket_number = jacket_number 
348
    session.commit()
349
    return True
350
 
1220 chandransh 351
def batch_orders(warehouseId):
352
    if not warehouseId:
353
        raise TransactionServiceException(101, "bad warehouse id")
1225 chandransh 354
 
355
    batchno_generator = BatchNoGenerator()
356
    session.commit()
1220 chandransh 357
    query = Order.query.filter_by(warehouse_id=warehouseId)
358
    query = query.filter_by(status=OrderStatus.SUBMITTED_FOR_PROCESSING)
359
    query = query.order_by(Order.created_timestamp)
360
    pending_orders = query.all()
1225 chandransh 361
 
1220 chandransh 362
    serial_no = 1
363
    for order in pending_orders:
1276 chandransh 364
        order.batchNo = batchno_generator.id
1220 chandransh 365
        order.serialNo = serial_no
366
        serial_no += 1
367
    session.commit() 
368
    pending_orders = query.all()
369
    return pending_orders
370
 
371
def order_outofstock(orderId):
372
    order = get_order(orderId)
373
    order.status = OrderStatus.INVENTORY_LOW
374
    order.statusDescription = "Low Inventory"
375
    order.outofstock_timestamp = datetime.datetime.now()
376
    session.commit()
377
    return True
378
 
759 chandransh 379
def mark_orders_as_manifested(warehouse_id, provider_id):
380
    try:
986 chandransh 381
        current_timestamp = datetime.datetime.now()
852 chandransh 382
        orders = Order.query.filter_by(warehouse_id = warehouse_id, logistics_provider_id = provider_id, status = OrderStatus.BILLED).all()
759 chandransh 383
        for order in orders:
384
            order.status = OrderStatus.SHIPPED_FROM_WH
987 chandransh 385
            order.statusDescription = "Order shipped from warehouse"
986 chandransh 386
            order.shipping_timestamp = current_timestamp
759 chandransh 387
        session.commit()
388
        return True
389
    except:
390
        return False
1113 chandransh 391
 
392
def mark_orders_as_picked_up(provider_id, pickup_details):
393
    for awb, pickup_timestamp in pickup_details.iteritems():
1135 chandransh 394
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1113 chandransh 395
        if order == None:
396
            raise TransactionServiceException(102, "No order found for the awb: " + awb)
397
        order.status = OrderStatus.SHIPPED_TO_LOGST
398
        order.statusDescription = "Order picked up by Courier Company"
1246 chandransh 399
        order.pickup_timestamp = pickup_timestamp
1113 chandransh 400
    session.commit()
1217 chandransh 401
 
1132 chandransh 402
    current_time = datetime.datetime.now()
403
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1246 chandransh 404
    from_datetime = to_datetime - datetime.timedelta(2)
1132 chandransh 405
    orders_not_picked_up = Order.query.filter_by(logistics_provider_id = provider_id).filter_by(status=OrderStatus.SHIPPED_FROM_WH).filter(Order.shipping_timestamp >= from_datetime).filter(Order.shipping_timestamp <= to_datetime).all()
1113 chandransh 406
    return orders_not_picked_up
407
 
1132 chandransh 408
def mark_orders_as_delivered(provider_id, delivered_orders):
409
    for awb, detail in delivered_orders.iteritems():
1135 chandransh 410
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1132 chandransh 411
        if order == None:
412
            raise TransactionServiceException(103, "No order found for the awb:" + awb)
413
        order.status = OrderStatus.DELIVERY_SUCCESS
414
        order.statusDescription = "Order delivered"
415
        order.delivery_timestamp, order.receiver = detail.split('|')
416
    session.commit()
417
 
1135 chandransh 418
def mark_orders_as_failed(provider_id, returned_orders):
419
    for awb, detail in returned_orders.iteritems():
420
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
421
        if order == None:
422
            raise TransactionServiceException(103, "No order found for the awb:" + awb)
423
        order.status = OrderStatus.FAILED
424
        order.delivery_timestamp, reason = detail.split('|')
425
        order.statusDescription = "Order Returned to Origin:" + reason
426
    session.commit()    
427
 
1246 chandransh 428
def update_non_delivery_reason(provider_id, undelivered_orders):
429
    for awb, reason in undelivered_orders.iteritems():
430
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
431
        if order == None:
432
            raise TransactionServiceException(103, "No order found for the awb:" + awb)
433
        order.statusDescription = reason
434
    session.commit()
435
 
483 rajveer 436
def get_alerts(order_id, all):
437
    query = Alerts.query.filter_by(order_id=order_id)
438
    if not all:
439
        query = query.filter_by(valid=True)
440
    return query.all()
441
 
442
def set_alert(order_id, unset, type, comment):
443
    #get existing alert
444
    if unset:
445
        query = Alerts.query.filter_by(order_id=order_id)
446
        query = query.filter_by(type=type)
447
        alerts = query.all()
448
        for alert in alerts:
449
            if alert.valid:
450
                alert.valid = False
451
                alert.comment = comment
452
                alert.time_unset = datetime.datetime.now()
453
    else:
454
        alert = Alerts()
455
        alert.order_id = order_id
456
        alert.valid = True
457
        alert.type = type
458
        alert.comment = comment
459
        alert.time_set = datetime.datetime.now()
766 rajveer 460
    session.commit()    
461
 
462
def close_session():
463
    if session.is_active:
464
        print "session is active. closing it."
465
        session.close()