Subversion Repositories SmartDukaan

Rev

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