/*
 * DataHandler.java
 *
 * Created on 10 de agosto de 2004, 17:52
 */

package com.fenalco.servlets.shopkeeper;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.fenalco.entities.DataAccess;
import com.fenalco.entities.Log;
import com.fenalco.entities.Order;
import com.fenalco.entities.Quote;
import com.fenalco.entities.ShoppingCart;
import com.fenalco.entities.Store;
import com.fenalco.entities.User;
import com.fenalco.utilities.MessageBuilder;
import com.fenalco.utilities.database.Transaction;
/**
 * Este Servlet administra toda las funciones relacionadas con el carrito de compras :
 * - Generar orden de pedido
 * - Guardar carrito de compras como lista
 * - Modificar cantidad de los productos del carrito
 * - Generar cotización
 * El tipo de operación es realizada de acuerdo con el valor del parámetro del <CODE>request</CODE>
 * <CODE>operationType</CODE>
 * @author Mario Linares Vásquez
 */
public class CartHandler extends HttpServlet {
    
    /**
     * Inicializa el servlet.
     * @param config
     * @throws ServletException
     */
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
       
    }
    
    /** Destructor de el servlet.
     */
    public void destroy() {
        
    }
    
    /**
     * Este método de acuerdo con el valor del parámetro <CODE>operationType</CODE> realiza las
     * siguientes acciones :
     *  - operationType = quote
     *      Toma el valor del parámetro <CODE>storeId</CODE> para invocar la función <CODE>submitQuotation</CODE>
     *  - operationType = order
     *      Toma el valor del parámetro <CODE>storeId</CODE> para invocar la función <CODE>submitOrder</CODE>
     *  - operationType = list
     *      Toma el valor del parámetro <CODE>listName</CODE> para invocar la función <CODE>saveList</CODE>
     *  - operationType = quantity
     *      Toma el valor de los parámetro <CODE>productId</CODE> y <CODE>newQuantity</CODE> para invocar la
     *      función <CODE>changeQuantity</CODE>
     * Al final del proceso el flujo es redireccionado al servlet micarrito
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException
     * @throws IOException
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
        HttpSession session = request.getSession(false);
        String url = "";
        String message = "";
        
        try
	    {
	        
	        if( session == null || ( User )session.getAttribute( "user" ) == null || ( ( User )session.getAttribute( "user" ) ).getRoleId() != 3 )
	        {
	            url="/index.jsp";
	            message = MessageBuilder.buildMessage(15);
	        }
	        else
	        {
	            String operationType = ( String )request.getAttribute( "operationType" );
	            
	            if( operationType.equals( "quantity" ) )
	            {
	                // aqui vienen los productos a los que se les va a cambiar
	                // la cantidad
	                Vector products = ( Vector )request.getAttribute( "products" );
	                boolean res = true;
	                for( int i = 0; i < products.size(); i++ )
	                {
	                    Integer[] data = ( Integer[] )products.elementAt( i );
	                    res = res && changeQuantity( data[ 0 ].intValue(), data[ 1 ].intValue(), 
	                        data[ 2 ].intValue(), session );
	                }
	                url = "/minorista/micarrito";
	                if( !res )
	                {
	                    message = "No todas las cantidades pudieron ser cambiadas debido a "
	                            + "que el valor establecido es menor que el mínimo";
	                }
	            }
	            // compra de los productos en el carrito
	            else if( operationType.equals( "order" ) )
	            {
	                //saco el carrito de compras de la sesión
	                ShoppingCart cart = ( ShoppingCart )session.getAttribute( "cart" );
	                
	                // si el carrito existe, procedo
	                if( cart != null ) 
	                {
	                    
	                    // primero obtengo el id del establecimiento
	                    boolean flag = true;
	                    Store store = ( Store )session.getAttribute( "store" );
	                    int storeId = store.getId();
	                    // el carrito me crea las ordenes
	                    Hashtable orders = cart.createOrders(storeId);
	                    
	                    Transaction transaction = new Transaction();
	                    
	                    Enumeration e = orders.keys();
	                    StringBuffer message2 = new StringBuffer("Las ordenes de los siguientes proveedores no" +
	                                            " cumplir con el valor mínimo de pedido :<br>"); 
	                    // recorro todas las ordenes
	                    while( e.hasMoreElements() )
	                    {
	                        // obtengo la orden
	                        Order order = ( Order )orders.get( e.nextElement() );
	                        
	                        // reviso si el pedido se hizo desde el call center
	                        if( session.getAttribute( "callcenter" ) != null )
	                        {
	                            order.setOrderOriginId( 3 );
	                        }
	                        else
	                        {
	                            order.setOrderOriginId( 1 );
	                        }
	                        
	                        
	                        double minimalOrder = DataAccess.getMinimalOrder(order.getCompanyId());
	                        order.calculateValue();
	                        double orderValue = order.getValue();
	                        
	                        if(orderValue < minimalOrder)
	                        {
	                            flag = false;
	                            message2.append(order.getCompanyName()+", pedido mínimo ="+DataAccess.getCurrency(minimalOrder)+"<br>");
	                        }
	                        
	                        if( flag )
	                        {
	                            // y le digo que se guarde en la BD
	                            order.saveData(transaction);
	                            order.submit();
	                            url = "/minorista/catalogo";
	                            
	                            // por cada pedido guardo un registro en el log
	                            try
	                            {
	                                Transaction t = new Transaction( );
	                                Log l = new Log( );
	                                User user = ( User )session.getAttribute( "user" );
	                                String userId = user.getLogin();
	                                String numberId = user.getIdentificationNumber();
	                                String externalUser = "";
	                                String description = "Envio de pedido al proveedor " + order.getCompanyId();
	                                User callcenter = ( User )session.getAttribute( "callcenter" );
	                                if( callcenter != null )
	                                {
	                                    externalUser = callcenter.getLogin();
	                                }
	                                l.saveData(userId, numberId, 15, description, externalUser, t );
	                                t.execute();
	                            }
	                            catch( Exception ex )
	                            {
	                                System.out.println( "Error guardando el Log." );
	                            }
	                        }
	                        
	                        
	                    }
	                    if(!flag)
	                    {
	                            message = message.concat(message2.toString());
	                            url = "/minorista/micarrito";
	                    }
	                    else
	                    {
	                        
	                        if( transaction.execute() )
	                            {
	                                message = "Su Pedido se ha realizado a cada proveedor.";
	                                
	                                 // limpio el carrito
	                                session.setAttribute( "cart", new ShoppingCart() );
	
	                            }
	                            else
	                            {
	                                message = "Su Pedido no se ha realizado correctamente, intente de nuevo";
	                            }
	                    }
	                    
	                    
	                }
	                
	                                
	            }
	            else if( operationType.equals( "list" ) )
	            {
	                String listName = ( String )request.getAttribute( "listName" );
	                
	                //saco el carrito de compras de la sesión
	                ShoppingCart cart = ( ShoppingCart )session.getAttribute( "cart" );
	                
	                // si el carrito existe, procedo
	                if( cart != null ) 
	                {
	                    // obtengo el id de la empresa
	                    Store store = ( Store )session.getAttribute( "store" );
	                    int companyId = store.getCompanyId();
	                    
	                    // creo la transacción para ejecutar las consultas
	                    Transaction transaction  = new Transaction();
	                    
	                    // le digo al carrito que salve la lista
	                    cart.saveList( companyId, listName, transaction );
	                    
	                    // ejecuto la transaccion
	                    if( transaction.execute() )
	                    {
	                        message = "La lista de compras se ha guardado con el nombre "
	                                + listName + ".";
	                        
	                            try
	                            {
	                                Transaction t = new Transaction( );
	                                Log l = new Log( );
	                                User user = ( User )session.getAttribute( "user" );
	                                String userId = user.getLogin();
	                                String numberId = user.getIdentificationNumber();
	                                String externalUser = "";
	                                User callcenter = ( User )session.getAttribute( "callcenter" );
	                                if( callcenter != null )
	                                {
	                                    externalUser = callcenter.getLogin();
	                                }
	                                l.saveData(userId, numberId, 16, message, externalUser, t );
	                                t.execute();
	                            }
	                            catch( Exception ex )
	                            {
	                                System.out.println( "Error guardando el Log." );
	                            }
	
	                    }
	                    else
	                    {
	                        message = "La lista no se ha podido guardar.";
	                    }
	                }
	
	                
	                url = "/minorista/catalogo";
	            }
	            else if( operationType.equals( "quote" ) )
	            {
	                //saco el carrito de compras de la sesión
	                ShoppingCart cart = ( ShoppingCart )session.getAttribute( "cart" );
	                
	                // si el carrito existe, procedo
	                if( cart != null ) 
	                {
	                    // primero obtengo el id del establecimiento
	                    Store store = ( Store )session.getAttribute( "store" );
	                    int storeId = store.getId();
	                    // el carrito me crea las cotizaciones
	                    Hashtable quotes = cart.createQuotes(storeId);
	                    
	                    Transaction transaction = new Transaction();
	                    
	                    Enumeration e = quotes.keys();
	                    // recorro todas las cotizaciones
	                    while( e.hasMoreElements() )
	                    {
	                        // obtengo la cotizacion
	                        Quote quote = ( Quote )quotes.get( e.nextElement() );
	                        // y le digo que se guarde en la BD
	                        
	                        quote.saveData(transaction);
	                        quote.submit( );
	                        
	                        // por cada cotización guardo un registro en el Log
	                        try
	                        {
	                            Transaction t = new Transaction( );
	                            Log l = new Log( );
	                            User user = ( User )session.getAttribute( "user" );
	                            String userId = user.getLogin();
	                            String numberId = user.getIdentificationNumber();
	                            String externalUser = "";
	                            String description = "Envio de cotización al proveedor " + quote.getSupplierId();
	                            User callcenter = ( User )session.getAttribute( "callcenter" );
	                            if( callcenter != null )
	                            {
	                                externalUser = callcenter.getLogin();
	                            }
	                            l.saveData(userId, numberId, 17, description, externalUser, t );
	                            t.execute();
	                        }
	                        catch( Exception ex )
	                        {
	                            System.out.println( "Error guardando el Log." );
	                        }
	
	                    }
	                    
	                    if( transaction.execute() )
	                    {
	                        message = "Su Cotizaci&oacute;n se ha enviado a cada proveedor.";
	                        
	                         // limpio el carrito
	                        session.setAttribute( "cart", new ShoppingCart() );
	
	                    }
	                    else
	                    {
	                        message = "Su Cotizaci&oacute; no se ha enviado correctamente, intente de nuevo";
	                    }
	                }
	                
	                
	                url = "/minorista/catalogo";
	                
	            }
	            else
	            {
	                url = "/asd";
	            }
	        }
	    }
        catch( Exception e )
	    {
	        url="/logout";
	        message = MessageBuilder.buildMessage(15);
	    }
        request.setAttribute( "message", message );
        RequestDispatcher rd = getServletContext().getRequestDispatcher( url );
        rd.forward( request, response );
        
    }
    
    /**
     * Procesa el método HTTP <code>GET</code>.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException
     * @throws IOException
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
    /**
     * Procesa el método HTTP <code>POST</code>.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException
     * @throws IOException
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
    /**
     * Retorna una breve descripción de el servlet.
     * @return
     */
    public String getServletInfo() {
        return "Short description";
    }
    
    
    /**
     * Este método toma el carrito de compras de la sesión para invocar la función
     * <CODE>changeQuantity</CODE> con los parámetros <CODE>productId</CODE> y <CODE>newQuantity</CODE>
     * @param productId id del producto del carrito a modificar cantidad
     * @param newQuantity nueva cantidad
     * @return <CODE>boolean</CODE> que representa el exito del proceso
     */    
    public boolean changeQuantity(int supplierId, int supplierProductId, int newQuantity, HttpSession session )
    {
        return ( ( ShoppingCart )session.getAttribute( "cart" ) ).changeQuantity( 
            supplierId, 
            supplierProductId, 
            newQuantity );
    }
    
    
    
    
}
