Subversion Repositories SmartDukaan

Rev

Rev 1493 | Rev 1565 | 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
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
180
    </div><hr />
181
    <div>
182
        <b>Order Details</b>
183
        <hr />
184
        <table>
185
        <tr>
186
            <th>Order No.</th>
187
            <th>Product</th>
188
            <th>Quantity</th>
189
            <th>Unit Price</th>
190
            <th>Amount</th>
191
        </tr>
192
    """
1398 varun.gupt 193
    user_email = ""
1262 varun.gupt 194
    total_amount = 0.0
195
    html_table = ""
196
 
197
    for order in transaction.orders:
198
        order_date = order.created_timestamp
1398 varun.gupt 199
        user_email = order.customer_email
1262 varun.gupt 200
        html_tr = "<tr><td>" + str(order.id) + "</td>"
201
 
202
        for lineitem in order.lineitems:
1276 chandransh 203
            html_tr += "<td>" + str(lineitem) + "</td>"
1262 varun.gupt 204
            html_tr += "<td>" + str(lineitem.quantity) + "</td>"
205
            html_tr += "<td>" + str(lineitem.unit_price) + "</td>"
206
            html_tr += "<td>" + str(lineitem.total_price) + "</td></tr>"
207
            total_amount += lineitem.total_price
208
            html_table += html_tr
209
    html_footer = """
210
        <tr><td colspan=5>&nbsp;</td></tr>
211
        <tr>
212
            <td colspan=4>Total Amount</td>
213
            <td>$total_amount</td>
214
        </tr>
215
        </table>
216
    </div><hr />
217
    <p>
218
        Best Wishes,<br />
219
        Saholic Team
220
    </p>
221
</div>
222
</body>
223
</html>
224
    """
1398 varun.gupt 225
 
1262 varun.gupt 226
    formated_order_date = order_date
227
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date))
228
    email_footer = Template(html_footer).substitute(dict(total_amount = total_amount))
229
 
1351 varun.gupt 230
    try:
231
        helper_client = HelperClient().get_client()
1398 varun.gupt 232
        helper_client.saveUserEmailForSending(user_email, "", "Saholic - Order Details", email_header + html_table + email_footer, str(transaction_id), "TransactionInfo")
1351 varun.gupt 233
        return True
234
    except Exception as e:
235
        print e
236
        return False
1262 varun.gupt 237
 
483 rajveer 238
def get_order(order_id):
239
    order = Order.get_by(id=order_id)
240
    if not order:
241
        raise TransactionServiceException(108, "no such order")
242
 
243
    return order
244
 
245
def get_orders_for_customer(customer_id, from_date, to_date, status):
246
    if not customer_id:
247
        raise TransactionServiceException(101, "bad customer id")
248
    query = Order.query.filter(Order.customer_id == customer_id)
249
    if status:
250
        query = query.filter(Order.status == status)
251
    if from_date:
252
        query = query.filter(Order.created_timestamp >from_date)
253
    if to_date:
254
        query = query.filter(Order.created_timestamp < to_date)
255
    return query.all()
256
 
1528 ankur.sing 257
def get_order_for_customer(order_id, customer_id):
258
    if not customer_id:
259
        raise TransactionServiceException(101, "bad customer id")
260
    order = get_order(order_id)
261
    if order.customer_id != customer_id:
262
        raise TransactionServiceException(108, "order: " + str(order_id) + " does not belong to customer: " + str(customer_id))
263
    return order
264
 
483 rajveer 265
def get_all_orders(status, from_date, to_date, warehouse_id):
266
    if not warehouse_id:
267
        raise TransactionServiceException(101, "bad warehouse id")
268
    query = Order.query.filter(Order.warehouse_id == warehouse_id)
269
    if status:
270
        query = query.filter(Order.status == status)
271
    if from_date:
272
        query = query.filter(Order.created_timestamp >from_date)
273
    if to_date:
274
        query = query.filter(Order.created_timestamp < to_date)
275
    return query.all()
276
 
1382 varun.gupt 277
def get_returnable_orders_for_customer(customer_id, limit = None):
278
    if not customer_id:
279
        raise TransactionServiceException(101, "bad customer id")
280
 
281
    query = Order.query.filter(Order.customer_id == customer_id)
282
    query = query.filter(Order.status != OrderStatus.PAYMENT_FAILED)
283
    query = query.filter(Order.status != OrderStatus.REJECTED)
284
    query = query.filter(Order.status > OrderStatus.SHIPPED_FROM_WH)
285
    query = query.filter(or_(Order.status < OrderStatus.DELIVERY_SUCCESS, Order.delivery_timestamp < datetime.datetime.now() + datetime.timedelta(hours = 48)))
286
    orders = query.all()
287
    order_ids = [order.id for order in orders]
288
    return order_ids
289
 
290
def get_cancellable_orders_for_customer(customer_id, limit = None):
291
    if not customer_id:
292
        raise TransactionServiceException(101, "bad customer id")
293
 
294
    query = Order.query.filter(Order.customer_id == customer_id)
295
    query = query.filter(Order.status != OrderStatus.REJECTED)
1483 varun.gupt 296
    query = query.filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING)
1382 varun.gupt 297
    query = query.filter(Order.status < OrderStatus.BILLED)
298
    orders = query.all()
299
    return [order.id for order in orders]
300
 
995 varun.gupt 301
def get_orders_by_billing_date(status, start_billing_date, end_billing_date, warehouse_id):
302
    if not warehouse_id:
303
        raise TransactionServiceException(101, "bad warehouse id")
304
 
305
    query = Order.query.filter(Order.warehouse_id == warehouse_id)
306
 
307
    if status:
308
        query = query.filter(Order.status == status)
309
 
310
    if start_billing_date:
311
        query = query.filter(Order.billing_timestamp >= start_billing_date)
312
 
313
    if end_billing_date:
314
        query = query.filter(Order.billing_timestamp <= end_billing_date)
315
 
316
    return query.all()
317
 
1528 ankur.sing 318
def get_orders_for_transaction(transaction_id, customer_id):
319
    orders = Order.query.filter_by(transaction_id=transaction_id, customer_id=customer_id).all()
320
 
1208 chandransh 321
    if not orders:
322
        raise TransactionServiceException(101, "No order for the transaction")
323
    return orders
324
 
1405 ankur.sing 325
def get_undelivered_orders(provider_id, warehouse_id):
326
    query = Order.query
327
    if provider_id != -1:
328
        query = query.filter_by(Order.logistics_provider_id == provider_id)
329
    if warehouse_id != -1:
330
        query = query.filter(Order.warehouse_id == warehouse_id)
331
    query = query.filter(and_(Order.status != OrderStatus.DELIVERY_SUCCESS, Order.status != OrderStatus.FAILED, \
332
                              Order.status > OrderStatus.SHIPPED_FROM_WH))
1479 ankur.sing 333
    #Get last midnight time instead of current time as courier company would have sent the 
334
    #delivery records updated at least till midnight and not by the current time.
335
    time_format = "%Y-%m-%d %H:%M:%S.%f"
336
    t = time.strptime(str(datetime.datetime.now()), time_format)
337
    midnightTime = datetime.datetime(*t[:3])
338
    query = query.filter(Order.expected_delivery_time < midnightTime)
1405 ankur.sing 339
    orders = query.all()
340
    return orders
341
 
1208 chandransh 342
def get_line_items_for_order(order_id):
343
    query = LineItem.query.filter(LineItem.order_id == order_id)
344
    return query.all()
345
 
483 rajveer 346
def change_order_status(self, orderId, status, description):
347
    order = get_order(orderId)
348
    order.status = status
349
    order.statusDescription = description
350
    session.commit()
351
    return True
352
 
921 rajveer 353
def accept_order(self, orderId):
354
    order = get_order(orderId)
355
    order.status = OrderStatus.ACCEPTED
356
    order.statusDescription = "Order Accepted"
357
    order.accepted_timestamp = datetime.datetime.now()
358
    session.commit()
359
    return True
360
 
361
def bill_order(self, orderId):
362
    order = get_order(orderId)
363
    order.status = OrderStatus.BILLED
364
    order.statusDescription = "Order Billed"
365
    order.billing_timestamp = datetime.datetime.now()
366
    session.commit()
1208 chandransh 367
    return True
921 rajveer 368
 
1149 chandransh 369
def add_billing_details(orderId, invoice_number, billed_by):
494 rajveer 370
    order = Order.get_by(id=orderId)
371
    if not order:
372
        raise TransactionServiceException(101, "No order found for the givem orderid")
373
    order.invoice_number = invoice_number
374
    order.billed_by = billed_by
375
    session.commit()
376
    return True
759 chandransh 377
 
1149 chandransh 378
def add_jacket_number(orderId, jacket_number):
379
    order = Order.get_by(id=orderId)
380
    if not order:
381
        raise TransactionServiceException(101, "No order found for the givem orderid")
382
    order.jacket_number = jacket_number 
383
    session.commit()
384
    return True
385
 
1220 chandransh 386
def batch_orders(warehouseId):
387
    if not warehouseId:
388
        raise TransactionServiceException(101, "bad warehouse id")
1225 chandransh 389
 
390
    batchno_generator = BatchNoGenerator()
391
    session.commit()
1220 chandransh 392
    query = Order.query.filter_by(warehouse_id=warehouseId)
393
    query = query.filter_by(status=OrderStatus.SUBMITTED_FOR_PROCESSING)
394
    query = query.order_by(Order.created_timestamp)
395
    pending_orders = query.all()
1225 chandransh 396
 
1220 chandransh 397
    serial_no = 1
398
    for order in pending_orders:
1276 chandransh 399
        order.batchNo = batchno_generator.id
1220 chandransh 400
        order.serialNo = serial_no
401
        serial_no += 1
402
    session.commit() 
403
    pending_orders = query.all()
404
    return pending_orders
405
 
406
def order_outofstock(orderId):
407
    order = get_order(orderId)
408
    order.status = OrderStatus.INVENTORY_LOW
409
    order.statusDescription = "Low Inventory"
410
    order.outofstock_timestamp = datetime.datetime.now()
411
    session.commit()
412
    return True
413
 
759 chandransh 414
def mark_orders_as_manifested(warehouse_id, provider_id):
415
    try:
986 chandransh 416
        current_timestamp = datetime.datetime.now()
852 chandransh 417
        orders = Order.query.filter_by(warehouse_id = warehouse_id, logistics_provider_id = provider_id, status = OrderStatus.BILLED).all()
759 chandransh 418
        for order in orders:
419
            order.status = OrderStatus.SHIPPED_FROM_WH
987 chandransh 420
            order.statusDescription = "Order shipped from warehouse"
986 chandransh 421
            order.shipping_timestamp = current_timestamp
759 chandransh 422
        session.commit()
423
        return True
424
    except:
425
        return False
1113 chandransh 426
 
427
def mark_orders_as_picked_up(provider_id, pickup_details):
428
    for awb, pickup_timestamp in pickup_details.iteritems():
1135 chandransh 429
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1113 chandransh 430
        if order == None:
431
            raise TransactionServiceException(102, "No order found for the awb: " + awb)
432
        order.status = OrderStatus.SHIPPED_TO_LOGST
433
        order.statusDescription = "Order picked up by Courier Company"
1246 chandransh 434
        order.pickup_timestamp = pickup_timestamp
1113 chandransh 435
    session.commit()
1217 chandransh 436
 
1132 chandransh 437
    current_time = datetime.datetime.now()
438
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1246 chandransh 439
    from_datetime = to_datetime - datetime.timedelta(2)
1132 chandransh 440
    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 441
    return orders_not_picked_up
442
 
1132 chandransh 443
def mark_orders_as_delivered(provider_id, delivered_orders):
444
    for awb, detail in delivered_orders.iteritems():
1135 chandransh 445
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1132 chandransh 446
        if order == None:
447
            raise TransactionServiceException(103, "No order found for the awb:" + awb)
448
        order.status = OrderStatus.DELIVERY_SUCCESS
449
        order.statusDescription = "Order delivered"
450
        order.delivery_timestamp, order.receiver = detail.split('|')
451
    session.commit()
452
 
1135 chandransh 453
def mark_orders_as_failed(provider_id, returned_orders):
454
    for awb, detail in returned_orders.iteritems():
455
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
456
        if order == None:
457
            raise TransactionServiceException(103, "No order found for the awb:" + awb)
458
        order.status = OrderStatus.FAILED
459
        order.delivery_timestamp, reason = detail.split('|')
460
        order.statusDescription = "Order Returned to Origin:" + reason
461
    session.commit()    
462
 
1246 chandransh 463
def update_non_delivery_reason(provider_id, undelivered_orders):
464
    for awb, reason in undelivered_orders.iteritems():
465
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
466
        if order == None:
467
            raise TransactionServiceException(103, "No order found for the awb:" + awb)
468
        order.statusDescription = reason
469
    session.commit()
470
 
483 rajveer 471
def get_alerts(order_id, all):
472
    query = Alerts.query.filter_by(order_id=order_id)
473
    if not all:
474
        query = query.filter_by(valid=True)
475
    return query.all()
476
 
477
def set_alert(order_id, unset, type, comment):
478
    #get existing alert
479
    if unset:
480
        query = Alerts.query.filter_by(order_id=order_id)
481
        query = query.filter_by(type=type)
482
        alerts = query.all()
483
        for alert in alerts:
484
            if alert.valid:
485
                alert.valid = False
486
                alert.comment = comment
487
                alert.time_unset = datetime.datetime.now()
488
    else:
489
        alert = Alerts()
490
        alert.order_id = order_id
491
        alert.valid = True
492
        alert.type = type
493
        alert.comment = comment
494
        alert.time_set = datetime.datetime.now()
766 rajveer 495
    session.commit()    
496
 
497
def close_session():
498
    if session.is_active:
499
        print "session is active. closing it."
500
        session.close()