Subversion Repositories SmartDukaan

Rev

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