Subversion Repositories SmartDukaan

Rev

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