Rev 1382 | Rev 1404 | 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 shop2020.thriftpy.utils.ttypes import HelperServiceException, Mailfrom 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_, or_from shop2020.model.v1 import orderfrom shop2020.clients.LogisticsClient import LogisticsClientfrom shop2020.clients.InventoryClient import InventoryClientfrom shop2020.clients.UserClient import UserClientfrom shop2020.clients.HelperClient import HelperClientdef 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 enqueue_transaction_info_email(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>"""user_email = ""total_amount = 0.0html_table = ""for order in transaction.orders:order_date = order.created_timestampuser_email = order.customer_emailhtml_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 = order_dateemail_header = Template(html_header).substitute(dict(order_date = formated_order_date))email_footer = Template(html_footer).substitute(dict(total_amount = total_amount))try:helper_client = HelperClient().get_client()helper_client.saveUserEmailForSending(user_email, "", "Saholic - Order Details", email_header + html_table + email_footer, str(transaction_id), "TransactionInfo")return Trueexcept Exception as e:print ereturn Falsedef 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_returnable_orders_for_customer(customer_id, limit = None):if not customer_id:raise TransactionServiceException(101, "bad customer id")query = Order.query.filter(Order.customer_id == customer_id)query = query.filter(Order.status != OrderStatus.PAYMENT_FAILED)query = query.filter(Order.status != OrderStatus.REJECTED)query = query.filter(Order.status > OrderStatus.SHIPPED_FROM_WH)query = query.filter(or_(Order.status < OrderStatus.DELIVERY_SUCCESS, Order.delivery_timestamp < datetime.datetime.now() + datetime.timedelta(hours = 48)))orders = query.all()order_ids = [order.id for order in orders]return order_idsdef get_cancellable_orders_for_customer(customer_id, limit = None):if not customer_id:raise TransactionServiceException(101, "bad customer id")query = Order.query.filter(Order.customer_id == customer_id)query = query.filter(Order.status != OrderStatus.PAYMENT_FAILED)query = query.filter(Order.status != OrderStatus.REJECTED)query = query.filter(Order.status < OrderStatus.BILLED)orders = query.all()return [order.id for order in orders]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()