Subversion Repositories SmartDukaan

Rev

Rev 3260 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#!/usr/bin/python

import optparse
import time
import datetime
import sys
from elixir import session

if __name__ == '__main__' and __package__ is None:
    import os
    sys.path.insert(0, os.getcwd())

from shop2020.clients.CatalogClient import CatalogClient
from shop2020.thriftpy.model.v1.order.ttypes import OrderStatus,\
    TransactionServiceException
from shop2020.model.v1.order.impl import DataService
from shop2020.model.v1.order.impl.DataAccessors import get_order,\
    order_outofstock, close_session

VALUES_TO_NAMES = {
    0: "PAYMENT_PENDING",
    1: "PAYMENT_FAILED",
    2: "INIT",
    3: "SUBMITTED_FOR_PROCESSING",
    4: "ACCEPTED",
    5: "INVENTORY_LOW",
    6: "REJECTED",
    7: "BILLED",
    8: "READY_FOR_SHIPPING",
    9: "SHIPPED_FROM_WH",
    10: "SHIPPED_TO_LOGST",
    11: "IN_TRANSIT",
    12: "DELIVERY_SUCCESS",
    13: "DELIVERY_FAILED_FIRST_ATTEMPT",
    14: "DELIVERY_FAILED_SECOND_ATTEMPT",
    15: "DELIVERY_FAILED_THIRD_ATTEMPT",
    16: "DELIVERY_FAILED_WORNG_ADDRESS",
    17: "COMPLETED",
    18: "CANCELED",
    19: "FAILED",
  }

def mark_order_as_picked_up(order):
    '''
    Mark order as picked up
    '''
    if order.status != OrderStatus.SHIPPED_FROM_WH:
        print "Has this order been picked up?"
        print
        print "In case it has been and the same was not updated in the database, please first mark this order as picked up and then try again."
        return

    raw_pickup_timestamp = raw_input("Enter pickup time in YYYY-MM-DD hhmm format: ")
    try:
        pickup_timestamp = get_py_datetime(raw_pickup_timestamp)
        print("Pick up timestamp: " + str(pickup_timestamp))
    except ValueError:
        print("Invalid pickup time")
        return
   
    order.status = OrderStatus.SHIPPED_TO_LOGST
    order.statusDescription = "Order picked up by Courier Company"
    order.pickup_timestamp = pickup_timestamp 
    session.commit()

def mark_order_as_delivered(order):
    '''
    Mark order as delivered
    '''
    if order.status != OrderStatus.SHIPPED_TO_LOGST:
        print "Has this order been picked up?"
        print
        print "In case it has been and the same was not updated in the database, please first mark this order as picked up and then try again."
        return

    raw_delivery_timestamp = raw_input("Enter delivery time in YYYY-MM-DD hhmm format: ")
    try:
        delivery_timestamp = get_py_datetime(raw_delivery_timestamp)
    except ValueError:
        print("Invalid delivery time stamp")
        return
    
    receiver = raw_input("Enter the name of receiver: ")
    if receiver is None or receiver == "":
        print("Receiver info is mandatory.")
        return
    
    order.status = OrderStatus.DELIVERY_SUCCESS
    order.statusDescription = "Order delivered"
    order.delivery_timestamp = delivery_timestamp
    order.receiver = receiver
    session.commit()


def mark_order_as_failed(order):
    '''
    Mark order as failed
    '''
    if order.status != OrderStatus.SHIPPED_TO_LOGST:
        print "Has this order been picked up?"
        print
        print "In case it has been and the same was not updated in the database, please first mark this order as picked up and then try again."
        return

    raw_delivery_timestamp = raw_input("Enter delivery time in YYYY-MM-DD hhmm format: ")
    try:
        delivery_timestamp = get_py_datetime(raw_delivery_timestamp)
    except ValueError:
        print("Invalid delivery timestamp")
        return
    
    reason = raw_input("Enter the reason for failure: ")
    if reason is None or reason == "":
        print("Reason for failure is mandatory.")
        return
    
    order.status = OrderStatus.FAILED
    order.delivery_timestamp = delivery_timestamp 
    order.statusDescription = "Order Returned to Origin:" + reason
    session.commit()

def change_product(order):
    '''
    Ship a product of a different color to the customer.
    '''
    if order.status not in [OrderStatus.INIT, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW]:
        print "This order has already been processed. Please seek help from engineering."
        return
    
    raw_item_id = raw_input("Enter the ID of the item that you want to ship: ")
    try:
        item_id = int(raw_item_id)
    except ValueError:
        print("Invalid product Id")
        return
    
    color = raw_input("Enter the color of the new item: ")
    if color is None or color == "":
        print("Color information is mandatory.")
        return
    
    #warehouse_id = raw_input("Enter the warehouse id which will fulfil this order. Leave empty to keep it unchanged: ")
    #if warehouse_id is None or warehouse_id == "":
    #    warehouse_id = order.warehouse_id
    
    lineitem = order.lineitems[0]
    
    catalog_client = CatalogClient().get_client()
    catalog_client.reserveItemInWarehouse(item_id, order.warehouse_id, lineitem.quantity)
    catalog_client.reduceReservationCount(lineitem.item_id, order.warehouse_id, lineitem.quantity)
    #TODO: Check that this new item has the same price
        
    lineitem.item_id = item_id
    lineitem.color = color
    
    session.commit()

def change_warehouse(order):
    '''
    Update the warehouse which will be used to fulfil this order.
    '''
    if order.status not in [OrderStatus.INIT, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW]:
        print "This order has already been processed. Please seek help from engineering."
        return
    
    print("Current Warehouse: " + str(order.warehouse_id))
    
    raw_warehouse_id = raw_input("Enter the ID of the warehouse from where you want to ship: ")
    try:
        warehouse_id = int(raw_warehouse_id)
    except ValueError:
        print("Invalid warehouse id")
        return
      
    if warehouse_id == order.warehouse_id:
        print("You have selected the current warehouse again. Nothing to do")
        return

    lineitem = order.lineitems[0]
    catalog_client = CatalogClient().get_client()
    catalog_client.reserveItemInWarehouse(lineitem.item_id, warehouse_id, lineitem.quantity)
    catalog_client.reduceReservationCount(lineitem.item_id, order.warehouse_id, lineitem.quantity)
    
    order.warehouse_id = warehouse_id
    session.commit()

def update_weight(order):
    '''
    Update the weight of order
    '''
    raw_weight = raw_input("Enter the final weight to be set: ")
    try:
        weight = float(raw_weight)
    except ValueError:
        print("Invalid weight")
        return
    
    order.total_weight = weight
    lineitem = order.lineitems[0]
    lineitem.total_weight = weight
    lineitem.unit_weight = weight
    #TODO: Update the weight of item. Problem is that even then, this update will only go to Production and not to Staging. Next content update will wipe out this data.
    session.commit()

def cancel(order):
    '''
    Cancel
    '''
    print("Your session has been closed")
    return

ACTIONS = {0: cancel,
           1: order_outofstock,
           2: mark_order_as_picked_up,
           3: mark_order_as_delivered,
           4: mark_order_as_failed,
           5: change_product,
           6: change_warehouse,
           7: update_weight
           }

def get_py_datetime(time_string):
    time_format = "%Y-%m-%d %H%M"
    mytime = time.strptime(time_string, time_format)
    return datetime.datetime(*mytime[:6])

def main():
    parser = optparse.OptionParser()
    parser.add_option("-H", "--host", dest="hostname",
                      default="localhost",
                      type="string", help="The HOST where the DB server is running",
                      metavar="HOST")
    (options, args) = parser.parse_args()
    if len(args) != 0:
        parser.error("You've supplied extra arguments. Are you sure you want to run this program?")
    DataService.initialize(db_hostname=options.hostname, echoOn=False)
    raw_order_id = raw_input("Enter Order Id which you want to modify:")
    try:
        order_id = int(raw_order_id)
        print("You want to modify: " + str(order_id))
    except ValueError:
        print("Invalid Order Id.")
        return
    
    try:
        order = get_order(order_id)
        print("Please check the details of the order below and ensure that it's the same order which you want to modify:")
        print("Order Id:\t\t" + str(order.id))
        print("Customer Name:\t\t" + order.customer_name)
        print("Address Line 1:\t\t" + order.customer_address1)
        print("Address Line 2:\t\t" + order.customer_address2)
        print("City:\t\t\t" + order.customer_city)
        print("State:\t\t\t" + order.customer_state)
        print("Pincode:\t\t" + order.customer_pincode)
        print("Amount:\t\t\t" + str(order.total_amount))
        print("Created On:\t\t" + str(order.created_timestamp))
        #print("Billed On:\t" + str(order.billing_timestamp))
        #print("Shipped On:\t" + str(order.shipping_timestamp))
        print("Current Status:\t\t" + VALUES_TO_NAMES[order.status])
        print("Status Description:\t" + order.statusDescription)
        print("Ordered Items description:")
        for lineitem in order.lineitems:
            print("Item Id:" + str(lineitem.item_id) + "\tBrand: " + str(lineitem.brand) + "\tModel: " + str(lineitem.model_number) + "\tColor: " + str(lineitem.color))
        print
        print
        print("You can perform following operations:")
        for (key, val) in ACTIONS.iteritems():
            print("[" + str(key) + "]" + val.__doc__ )

        raw_action = raw_input("What do you want to do? ")
        if raw_action is None or raw_action == "":
            print("Your session has been closed.")
            return
        try:
            action = int(raw_action)
        except ValueError:
            print("Invalid input.")
            return
        if action > max(ACTIONS.keys()):
            print("Invalid input.")
            return
        ACTIONS[action](order)
    except TransactionServiceException as tsex:
        print tsex.message
    finally:
        close_session()
    
if __name__ == '__main__':
    main()