Rev 1334 | Rev 1382 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
'''Created on 29-Mar-2010@author: ashish'''from string import Templatefrom email.mime.multipart import MIMEMultipartfrom shop2020.thriftpy.utils.ttypes import HelperServiceException, Mailfrom email.mime.base import MIMEBasefrom email import encodersfrom email.mime.text import MIMETextimport osimport smtplibimport timefrom time import strftimefrom shop2020.model.v1.order.impl.DataService import Transaction, LineItem,\Alerts, Order, BatchNoGeneratorfrom shop2020.thriftpy.model.v1.order.ttypes import Transaction as T_Transaction,\TransactionServiceException, TransactionStatus, OrderStatusimport datetimefrom elixir import *from shop2020.utils.Utils import to_py_date, to_java_datefrom sqlalchemy.sql.expression import and_from shop2020.model.v1 import orderfrom shop2020.clients.LogisticsClient import LogisticsClientfrom shop2020.clients.InventoryClient import InventoryClientfrom shop2020.clients.UserClient import UserClientdef get_new_transaction():transaction = Transaction()transaction.createdOn = datetime.datetime.now()transaction.status = TransactionStatus.INITtransaction.status_message = "New transaction"return transactiondef create_order(t_order):order = Order()if t_order.warehouse_id:order.warehouse_id = t_order.warehouse_idif t_order.logistics_provider_id:order.logistics_provider_id = t_order.logistics_provider_idorder.airwaybill_no = t_order.airwaybill_noorder.tracking_id = t_order.tracking_idif t_order.expected_delivery_time:order.expected_delivery_time = to_py_date(t_order.expected_delivery_time)if t_order.customer_id:order.customer_id = t_order.customer_idorder.customer_name = t_order.customer_nameorder.customer_city = t_order.customer_cityorder.customer_state = t_order.customer_stateorder.customer_mobilenumber = t_order.customer_mobilenumberorder.customer_pincode = t_order.customer_pincodeorder.customer_address1 = t_order.customer_address1order.customer_address2 = t_order.customer_address2order.customer_email = t_order.customer_email#new status and status description to be addedorder.status = t_order.statusorder.statusDescription = t_order.statusDescriptionorder.total_amount = t_order.total_amountorder.total_weight = t_order.total_weightif t_order.created_timestamp:order.created_timestamp = to_py_date(t_order.created_timestamp)else:order.created_timestamp = datetime.datetime.now()return orderdef create_transaction(t_transaction):t_orders = t_transaction.ordersif not t_orders:raise TransactionServiceException(101, "Orders missing from the transaction")transaction = get_new_transaction()transaction.customer_id = t_transaction.customer_idtransaction.shopping_cart_id = t_transaction.shoppingCartidfor t_order in t_orders:order = create_order(t_order)order.transaction = transactionfor line_item in t_order.lineitems:litem = LineItem()litem.item_id = line_item.item_idlitem.productGroup = line_item.productGrouplitem.brand = line_item.brandif line_item.model_number:litem.model_number = line_item.model_numberif line_item.model_name:litem.model_name = line_item.model_nameif line_item.color:litem.color = line_item.colorif line_item.extra_info:litem.extra_info = line_item.extra_infolitem.quantity = line_item.quantitylitem.unit_price = line_item.unit_pricelitem.unit_weight = line_item.unit_weightlitem.total_price = line_item.total_pricelitem.total_weight = line_item.total_weightlitem.transfer_price = line_item.transfer_price"""if line_item.addedOn:litem.added_on = to_py_date(line_item.addedOn)else:litem.added_on = datetime.datetime.now()"""litem.order = ordersession.commit()return transaction.iddef get_transaction(transaction_id):transaction = Transaction.get_by(id=transaction_id)if not transaction:raise TransactionServiceException(108, "no such transaction")return transactiondef get_transactions_for_customer(customer_id, from_date, to_date, status):if not customer_id:raise TransactionServiceException(101, "bad customer id")query = Transaction.query.filter(Transaction.customer_id == customer_id)if status:query = query.filter(Transaction.status == status)if from_date:query = query.filter(Transaction.createdOn >from_date)if to_date:query = query.filter(Transaction.createdOn < to_date)return query.all()def get_transactions_for_shopping_cart_id(shopping_cart_id):transactions = Transaction.query.filter_by(shopping_cart_id=shopping_cart_id).all()if not transactions:raise TransactionServiceException(108, "transactions for this shopping cart")return transactionsdef get_transaction_status(transaction_id):if not transaction_id:raise TransactionServiceException(101, "bad transaction id")transaction = get_transaction(transaction_id)return transaction.statusdef change_transaction_status(transaction_id, new_status, description):transaction = get_transaction(transaction_id)transaction.status = new_statustransaction.status_message = descriptionif new_status == TransactionStatus.FAILED:for order in transaction.orders:order.status = OrderStatus.PAYMENT_FAILEDelif new_status == TransactionStatus.IN_PROCESS:for order in transaction.orders:order.status = OrderStatus.SUBMITTED_FOR_PROCESSINGorder.statusDescription = "Submitted to warehouse"#After we got payment success, we will set logistics info alsologistics_client = LogisticsClient().get_client()#FIXME line item is only one now. If multiple will come, need to fix.item_id = order.lineitems[0].item_idlogistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id)order.warehouse_id = logistics_info.warehouseIdorder.logistics_provider_id = logistics_info.providerIdorder.airwaybill_no = logistics_info.airway_billnoorder.tracking_id = order.airwaybill_noorder.expected_delivery_time = datetime.datetime.now() + datetime.timedelta(days=logistics_info.deliveryTime)catalog_client = InventoryClient().get_client()catalog_client.reserveItemInWarehouse(item_id, logistics_info.warehouseId, order.lineitems[0].quantity)item_pricing = catalog_client.getItemPricing(item_id, order.warehouse_id)order.lineitems[0].transfer_price = item_pricing.transferPricetry:#Email the information of order placed to customeremail_transaction_info_to_user(transaction_id)except Exception as ex:#Nothing much to do. Customer will not know that there was a transaction.print exsession.commit()return Truedef email_transaction_info_to_user(transaction_id):transaction = get_transaction(transaction_id)html_header = """<html><body><div><p>Hello,<br /><br />Thanks for your placing your order with us. Following are the details of your order:</p><div>Order Date: $order_date</div><hr /><div><b>Order Details</b><hr /><table><tr><th>Order No.</th><th>Product</th><th>Quantity</th><th>Unit Price</th><th>Amount</th></tr>"""total_amount = 0.0html_table = ""for order in transaction.orders:order_date = order.created_timestamphtml_tr = "<tr><td>" + str(order.id) + "</td>"for lineitem in order.lineitems:html_tr += "<td>" + str(lineitem) + "</td>"html_tr += "<td>" + str(lineitem.quantity) + "</td>"html_tr += "<td>" + str(lineitem.unit_price) + "</td>"html_tr += "<td>" + str(lineitem.total_price) + "</td></tr>"total_amount += lineitem.total_pricehtml_table += html_trhtml_footer = """<tr><td colspan=5> </td></tr><tr><td colspan=4>Total Amount</td><td>$total_amount</td></tr></table></div><hr /><p>Best Wishes,<br />Saholic Team</p></div></body></html>"""# formated_order_date = strftime("%B %d, %Y %H:%M %p", time.strptime(order_date, "%Y-%m-%d %H:%M:%S"))formated_order_date = order_dateemail_header = Template(html_header).substitute(dict(order_date = formated_order_date))email_footer = Template(html_footer).substitute(dict(total_amount = total_amount))user_client = UserClient().get_client()user = user_client.getUserById(transaction.customer_id)sendMail(Email(email_header + html_table + email_footer, "Saholic - Order Details", user.email))return Trueclass Email:def __init__(self, message, subject, to):self.data = messageself.sender = ''self.subject = subjectself.to = [to]def sendMail(mail):if not mail:raise Exception(101, "mail not present")#msg = MIMEMultipart()#mail = Mail()if mail.sender:mail.data = "This mail is sent by " + mail.sender + "\n" + mail.datamsg = MIMEText(mail.data, 'html')msg['To'] = ', '.join( mail.to )if mail.sender:msg['From'] = mail.senderelse:msg['From'] = "help@saholic.com"msg['Subject'] = mail.subject#msg.attach(mail.data)for to in mail.to:mail.sender = "help@shop2020.in"mail.password = "5h0p2o2o"mailServer = smtplib.SMTP("smtp.gmail.com", 587)mailServer.ehlo()mailServer.starttls()mailServer.ehlo()mailServer.login(mail.sender, mail.password)mailServer.sendmail(mail.password, to, msg.as_string())# Should be mailServer.quit(), but that crashes...mailServer.close()def get_order(order_id):order = Order.get_by(id=order_id)if not order:raise TransactionServiceException(108, "no such order")return orderdef get_orders_for_customer(customer_id, from_date, to_date, status):if not customer_id:raise TransactionServiceException(101, "bad customer id")query = Order.query.filter(Order.customer_id == customer_id)if status:query = query.filter(Order.status == status)if from_date:query = query.filter(Order.created_timestamp >from_date)if to_date:query = query.filter(Order.created_timestamp < to_date)return query.all()def get_all_orders(status, from_date, to_date, warehouse_id):if not warehouse_id:raise TransactionServiceException(101, "bad warehouse id")query = Order.query.filter(Order.warehouse_id == warehouse_id)if status:query = query.filter(Order.status == status)if from_date:query = query.filter(Order.created_timestamp >from_date)if to_date:query = query.filter(Order.created_timestamp < to_date)return query.all()def get_orders_by_billing_date(status, start_billing_date, end_billing_date, warehouse_id):if not warehouse_id:raise TransactionServiceException(101, "bad warehouse id")query = Order.query.filter(Order.warehouse_id == warehouse_id)if status:query = query.filter(Order.status == status)if start_billing_date:query = query.filter(Order.billing_timestamp >= start_billing_date)if end_billing_date:query = query.filter(Order.billing_timestamp <= end_billing_date)return query.all()def get_orders_for_transaction(transaction_id):orders = Order.query.filter_by(transaction_id=transaction_id).all()if not orders:raise TransactionServiceException(101, "No order for the transaction")return ordersdef get_line_items_for_order(order_id):query = LineItem.query.filter(LineItem.order_id == order_id)return query.all()def change_order_status(self, orderId, status, description):order = get_order(orderId)order.status = statusorder.statusDescription = descriptionsession.commit()return Truedef accept_order(self, orderId):order = get_order(orderId)order.status = OrderStatus.ACCEPTEDorder.statusDescription = "Order Accepted"order.accepted_timestamp = datetime.datetime.now()session.commit()return Truedef bill_order(self, orderId):order = get_order(orderId)order.status = OrderStatus.BILLEDorder.statusDescription = "Order Billed"order.billing_timestamp = datetime.datetime.now()session.commit()return Truedef add_billing_details(orderId, invoice_number, billed_by):order = Order.get_by(id=orderId)if not order:raise TransactionServiceException(101, "No order found for the givem orderid")order.invoice_number = invoice_numberorder.billed_by = billed_bysession.commit()return Truedef add_jacket_number(orderId, jacket_number):order = Order.get_by(id=orderId)if not order:raise TransactionServiceException(101, "No order found for the givem orderid")order.jacket_number = jacket_numbersession.commit()return Truedef batch_orders(warehouseId):if not warehouseId:raise TransactionServiceException(101, "bad warehouse id")batchno_generator = BatchNoGenerator()session.commit()query = Order.query.filter_by(warehouse_id=warehouseId)query = query.filter_by(status=OrderStatus.SUBMITTED_FOR_PROCESSING)query = query.order_by(Order.created_timestamp)pending_orders = query.all()serial_no = 1for order in pending_orders:order.batchNo = batchno_generator.idorder.serialNo = serial_noserial_no += 1session.commit()pending_orders = query.all()return pending_ordersdef order_outofstock(orderId):order = get_order(orderId)order.status = OrderStatus.INVENTORY_LOWorder.statusDescription = "Low Inventory"order.outofstock_timestamp = datetime.datetime.now()session.commit()return Truedef mark_orders_as_manifested(warehouse_id, provider_id):try:current_timestamp = datetime.datetime.now()orders = Order.query.filter_by(warehouse_id = warehouse_id, logistics_provider_id = provider_id, status = OrderStatus.BILLED).all()for order in orders:order.status = OrderStatus.SHIPPED_FROM_WHorder.statusDescription = "Order shipped from warehouse"order.shipping_timestamp = current_timestampsession.commit()return Trueexcept:return Falsedef mark_orders_as_picked_up(provider_id, pickup_details):for awb, pickup_timestamp in pickup_details.iteritems():order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()if order == None:raise TransactionServiceException(102, "No order found for the awb: " + awb)order.status = OrderStatus.SHIPPED_TO_LOGSTorder.statusDescription = "Order picked up by Courier Company"order.pickup_timestamp = pickup_timestampsession.commit()current_time = datetime.datetime.now()to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)from_datetime = to_datetime - datetime.timedelta(2)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()return orders_not_picked_updef mark_orders_as_delivered(provider_id, delivered_orders):for awb, detail in delivered_orders.iteritems():order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()if order == None:raise TransactionServiceException(103, "No order found for the awb:" + awb)order.status = OrderStatus.DELIVERY_SUCCESSorder.statusDescription = "Order delivered"order.delivery_timestamp, order.receiver = detail.split('|')session.commit()def mark_orders_as_failed(provider_id, returned_orders):for awb, detail in returned_orders.iteritems():order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()if order == None:raise TransactionServiceException(103, "No order found for the awb:" + awb)order.status = OrderStatus.FAILEDorder.delivery_timestamp, reason = detail.split('|')order.statusDescription = "Order Returned to Origin:" + reasonsession.commit()def update_non_delivery_reason(provider_id, undelivered_orders):for awb, reason in undelivered_orders.iteritems():order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()if order == None:raise TransactionServiceException(103, "No order found for the awb:" + awb)order.statusDescription = reasonsession.commit()def get_alerts(order_id, all):query = Alerts.query.filter_by(order_id=order_id)if not all:query = query.filter_by(valid=True)return query.all()def set_alert(order_id, unset, type, comment):#get existing alertif unset:query = Alerts.query.filter_by(order_id=order_id)query = query.filter_by(type=type)alerts = query.all()for alert in alerts:if alert.valid:alert.valid = Falsealert.comment = commentalert.time_unset = datetime.datetime.now()else:alert = Alerts()alert.order_id = order_idalert.valid = Truealert.type = typealert.comment = commentalert.time_set = datetime.datetime.now()session.commit()def close_session():if session.is_active:print "session is active. closing it."session.close()