/* 
 * OrderList.java
 *
 * Created on 12 de agosto de 2004, 11:36 --> fecha de creación del archivo
 */

package com.fenalco.entities;

import java.sql.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import com.fenalco.utilities.database.QueryException;
import com.fenalco.utilities.database.SQLUtilities;

/**
 * Esta clase representa un listado de pedidos organizados de acuerdo a quien lo
 * solicita, por ejemplo un minorista o un proveedor
 * 
 * @author Néstor Romero León
 */
public class OrderList
{
	/**
	 * Este <CODE>Hashtable</CODE> se utiliza para organizar los pedidos que
	 * forman parte del listado, esta organizado de la siguiente forma: key:
	 * identificador del pedido <CODE>orderId</CODE> value: Objeto del tipo
	 * <CODE>Order</CODE>
	 */
	private Vector orders;

	/**
	 * Constructor por defecto del objeto, permite crear un listado general de
	 * todos los pedidos del sistema, por medio de un llamado al método <CODE>
	 * loadData()</CODE>.
	 */
	public OrderList( )
	{
		this.orders = new Vector();
		this.loadData();
	}

	/**
	 * Constructor que permite crear un listado vacio o un listado general de
	 * todos los pedidos del sistema, por medio de un llamado al método <CODE>
	 * loadData()</CODE>.
         * @param empty Indica si el listado se crea vacio o no
	 */
	public OrderList(boolean empty )
	{
		this.orders = new Vector();
                if(!empty){
                    this.loadData();
                }
	}
        
	/**
	 * Este constructor sirve para que el administrador construya un listado con
	 * los pedidos realizados o recibidos por una empresa en particular dentro
	 * de un rango de fechas.
	 * 
	 * @param companyId
	 *            Identificador de la empresa
	 * @param companyRole
	 *            Rol de la empresa a consultar
	 * @param startDate
	 *            Fecha de inicio
	 * @param endDate
	 *            Fecha de terminación
	 */
	public OrderList( int companyId, String companyRole, Date startDate,
			Date endDate)
	{
		this.orders = new Vector();
		this.loadData(companyId, companyRole, startDate, endDate);
	}

	/**
	 * Constructor, permite generar un listado de pedidos filtrado de manera
	 * específica de acuerdo a los parámetros recibidos de la siguiente forma:
	 * 
	 * Un minorista puede solicitar un listado de los pedidos hechos a un
	 * proveedor específico.
	 * 
	 * Un proveedor puede solicitar un listado de los pedidos recibidos de un
	 * minorista específico.
	 * 
	 * Los parámetros de fechas se utilizan para limitar el listado entre una
	 * fecha inicial y una final.
	 * 
	 * Todos los parámetros pueden recibir un valor por defecto (-1)
	 * correspondiente a todos, por ejemplo todos los minoristas, todos los
	 * proveedores o cualquier fecha.
	 * 
	 * 
	 * El parámetro del rol se utiliza para identificar la forma de construir el
	 * listado.
	 * 
	 * Este constructor llama al método <CODE>loadData(params)</CODE> para
	 * cargar el listado desde la base de datos.
	 * 
	 * @param requestCompanyId
	 *            Id de la empresa que solicita el listado
	 * @param responseCompanyId
	 *            Empresa objetivo del listado
	 * @param requestRole
	 *            Rol de la empresa que solicita el listado
	 * @param startDate
	 *            Fecha desde la cual buscar pedidos
	 * @param endDate
	 *            Fecha hasta la cual buscar pedidos
	 */
	public OrderList( int requestCompanyId, int responseCompanyId,
			String requestRole, Date startDate, Date endDate, int order,
			boolean historical)
	{
		this.orders = new Vector();
		this.loadData(requestCompanyId, responseCompanyId, requestRole,
				startDate, endDate, order, historical);
	}

	/**
	 * Este método permite crear un listado de los pedidos mas recientes que se
	 * encuentran dentro del Hashtable orders, retorna el número de pedidos que
	 * recibe como parámetro.
	 * 
	 * Este método requiere que el Hastable orders tenga asignados pedidos,
	 * internamente deberá llamar al constructor de <CODE>OrderList</CODE>
	 * para poder retornar este objeto con los pedidos seleccionados.
	 * 
	 * @param numberOfOrders
	 *            Número de pedidos a seleccionar como más recientes
	 * @return Objeto <CODE>OrderList</CODE> que agrupa los pedidos más
	 *         recientes que se encuentran dentro del atributo orders.
	 */
	public void latestOrderList( int numOrders )
	{
		
                int count = 0;
                Enumeration keys = this.orders.elements();
		Vector auxResult = new Vector();

		while( keys.hasMoreElements() )
		{
			Order order = ( Order ) keys.nextElement();
			if( /*order.getOrderStatus() == 3 &&*/ count < numOrders )
			{
				auxResult.addElement(order);
                                count++;
			}
                        
		}
                
                /*
                if( auxResult.size() > numOrders )
		{
			for( int i = numOrders - 1; i < auxResult.size(); i++ )
			{
                                System.out.println( i );
                                
				auxResult.remove(i);
			}
		}
                */
                
		this.setOrders( auxResult );
                
	}

	/**
	 * Este método carga un listado general de los pedidos de la base de datos
	 * por medio de un llamado al método <CODE>query</CODE> de la clase <CODE>
	 * SQLUtilities</CODE>.
	 * 
	 * @return Valor booleano que indica si la operación tuvo éxito o no.
	 */
	public boolean loadData( )
	{
		boolean response = true;
		Vector result = new Vector();
		Hashtable aux = new Hashtable();
		String sql = "SELECT pedi_id,pedi_fecha " + "FROM pedido "
				+ "ORDER BY pedi_fecha DESC;";

		try
		{
			result = SQLUtilities.query(sql);
			for( int i = 0; i < result.size(); i++ )
			{
				aux = (Hashtable) result.elementAt(i);
				this.orders.addElement(new Order(((Integer) aux.get("pedi_id"))
						.intValue()));
			}
		}
		catch (QueryException qe)
		{
			response = false;
		}
		return response;
	}

	/**
	 * Este método recibe los parámetros enviados por el constructor <CODE>
	 * OrderList(params)</CODE> y carga los pedidos desde la base de datos de
	 * acuerdo a dichos parámetros, mediante un llamado al método <CODE>query
	 * </CODE> de la clase <CODE>SQLUtilities</CODE>.
	 * 
	 * @param requestCompanyId
	 *            Id de la empresa que solicita el listado
	 * @param responseCompanyId
	 *            Empresa objetivo del listado
	 * @param requestRole
	 *            Rol de la empresa que solicita el listado SOLO puede tener los
	 *            valores Minorista o Proveedor
	 * @param startDate
	 *            Fecha desde la cual buscar pedidos
	 * @param endDate
	 *            Fecha hasta la cual buscar pedidos
	 * @return Valor booleano que indica si la operación tuvo éxito o no.
	 */
	public boolean loadData( int requestCompanyId, int responseCompanyId,
			String requestRole, Date startDate, Date endDate, int order,
			boolean historical )
	{
		boolean response = true;
		Vector result = new Vector();
		Hashtable aux = new Hashtable();
		String sql = new String();
                
		String ordersResponseShopkeeper = "AND establecimiento.empr_id="
				+ responseCompanyId + " ";
                
		String ordersRequestShopkeeper = "AND establecimiento.empr_id ="
				+ requestCompanyId + " ";
                
		String ordersResponseSupplier = "AND pedido.empr_id="
				+ responseCompanyId + " ";
                
		String ordersRequestSupplier = "AND pedido.empr_id=" + requestCompanyId
				+ " ";
                
		String ordersDateRange = "AND pedi_fecha BETWEEN \'" + startDate
				+ "\' AND \'" + endDate + "\' ";

		String historicalSupplier = "SELECT pedi_hist_id,pedi_hist_fecha "
				+ "FROM pedido_historico, establecimiento "
				+ "WHERE establecimiento.esta_id = pedi_hist_establecimiento_id ";

		String historicalShopKeeper = "SELECT pedi_hist_id, pedi_hist_fecha "
				+ "FROM pedido_historico, establecimiento "
				+ "WHERE establecimiento.esta_id = pedido_historico.esta_id ";

		String historicalSysManager = "SELECT pedi_hist_id, pedi_hist_fecha "
				+ "FROM pedido_historico " + "WHERE (pedi_hist_id>=-1 OR pedi_hist_id<-1) "; //para
																	   // cuando
																	   // vienen
																	   // fechas

		String historicalOrdersResponseSupplier = "AND pedido_historico.pedi_hist_empresa_id="
				+ responseCompanyId + " ";
                
		String historicalOrdersRequestSupplier = "AND pedido_historico.pedi_hist_empresa_id="
				+ requestCompanyId + " ";
                
		String historicalOrdersDateRange = "AND pedi_hist_fecha BETWEEN \'"
				+ startDate + "\' AND \'" + endDate + "\' ";

		if( requestCompanyId < 0 )
		{
			return false;
		}

		if( requestRole.equals("Proveedor") )
		{
			//Pedidos recibidos por un proveedor de un minorista específico

			if( !historical )
			{
				sql = new String("SELECT pedi_id,pedi_fecha "
						+ "FROM pedido,establecimiento "
						+ "WHERE establecimiento.esta_id = pedido.esta_id ");
				sql = sql.concat(ordersRequestSupplier);
			}
			else
			{
				sql = new String(historicalSupplier);
				sql = sql.concat(historicalOrdersRequestSupplier);
			}
			//Hay un minorista específico
			if( responseCompanyId > -1 )
			{
				sql = sql.concat(ordersResponseShopkeeper);
			}

		}
		else
			if( requestRole.equals("Minorista") )
			{
				//Pedidos enviados por un minorista a un proveedor
				if( !historical )
				{
					sql = new String("SELECT pedi_id,pedi_fecha "
							+ "FROM pedido, establecimiento "
							+ "WHERE establecimiento.esta_id = pedido.esta_id ");
				}
				else
				{
					sql = new String(historicalShopKeeper);
				}

				sql = sql.concat(ordersRequestShopkeeper);

				//Hay un proveedor específico
				if( responseCompanyId > -1 )
				{
					if( !historical )
					{
						sql = sql.concat(ordersResponseSupplier);
					}
					else
					{
						sql = sql.concat(historicalOrdersResponseSupplier);
					}

				}
			}
			else
				if( requestRole.equals("Administrador") )
				{
					if( !historical )
					{
						sql = new String("SELECT pedi_id,pedi_fecha "
								+ "FROM pedido " + "WHERE (pedi_id>=-1 OR pedi_id<-1) "); //para
																		 // cuando
																		 // vienen
																		 // fechas
					}
					else
					{
						sql = new String( historicalSysManager );
					}
				}

		//Hay un rango de fechas establecido
		if( startDate.getTime() > 0 )
		{
			if( !historical )
			{
				sql = sql.concat(ordersDateRange);
			}
			else
			{
				sql = sql.concat(historicalOrdersDateRange);
			}
		}

		switch (order)
		{
			case 1:
				//Empresa
				if( requestRole.equals("Minorista") )
				{
					//sql = sql.concat("ORDER BY DESC;");
				}
				else
				{
					sql = sql.concat("ORDER BY empr_nombre DESC;");
				}
				break;
			case 2:
				//Fecha
				//sql = sql.concat("ORDER BY pedi_fecha DESC;");
				if( !historical )
				{
					sql = sql.concat("ORDER BY pedi_fecha DESC;");
				}
				else
				{
					sql = sql.concat("ORDER BY pedi_hist_fecha DESC;");
				}
				break;
			case 3:
				//Valor

				break;
			case 4:
				//Estado
				if( !historical )
				{
					sql = sql.concat("ORDER BY esta_pedi_id ASC");
				}
				else
				{
					sql = sql
							.concat("ORDER BY pedi_hist_estado_pedido_id ASC;");
				}
				break;
		}

		System.out.println("SQL-> "+sql);

		try
		{
			result = SQLUtilities.query(sql);
			for( int i = 0; i < result.size(); i++ )
			{
				aux = (Hashtable) result.elementAt(i);
				if( !historical )
				{
					this.orders.addElement(new Order(((Integer) aux
							.get("pedi_id")).intValue()));
				}
				else
				{
					Order o = new Order();
					o.loadHistoricalOrder(((Integer) aux.get("pedi_hist_id"))
							.intValue());
					this.orders.addElement(o);
				}

			}
		}
		catch (QueryException qe)
		{
			response = false;
		}
		return response;
	}

	/**
	 * Este método construye un listado con los pedidos recibidos o realizados
	 * por una empresa en particular, dentro de un rango establecido de fechas.
	 * Para el uso del administrador
	 * 
	 * @param companyId
	 *            Identificador de la empresa
	 * @param companyRole
	 *            Rol de la empresa SOLO puede tener los valores Minorista o
	 *            Proveedor
	 * @param startDate
	 *            Fecha de inicio
	 * @param endDate
	 *            Fecha de terminación
	 * @return Valor booleano que indica si la operación tuvo éxito o no.
	 */
	public boolean loadData( int companyId, String companyRole, Date startDate,
			Date endDate )
	{
		boolean response = true;
		Vector result = new Vector();
		Hashtable aux = new Hashtable();
		String sql = new String();
		String ordersDateRange = "AND pedi_fecha BETWEEN \'" + startDate
				+ "\' AND \'" + endDate + "\' ";

		if( companyId < 0 )
		{
			return false;
		}

		if( companyRole.equals("Minorista") )
		{
			sql = new String("SELECT pedi_id,pedi_fecha "
					+ "FROM pedido,establecimiento "
					+ "WHERE pedido.esta_id=establecimiento.esta_id AND "
					+ "establecimiento.empr_id=" + companyId + " ");
		}
		else
		{
			sql = new String("SELECT pedi_id,pedi_fecha "
					+ "FROM pedido "
					+ "WHERE pedido.empr_id=" + companyId + " ");
		}

		//Hay un rango de fechas establecido
		if( startDate.getTime() > 0 )
		{
			sql = sql.concat(ordersDateRange);
		}
		
                sql = sql.concat("ORDER BY pedi_fecha DESC;");

                System.out.println("En OrderList-> "+sql);
                
		try
		{
			result = SQLUtilities.query(sql);
			for( int i = 0; i < result.size(); i++ )
			{
				aux = (Hashtable) result.elementAt(i);
				this.orders.addElement(new Order(((Integer) aux.get("pedi_id"))
						.intValue()));
			}
		}
		catch (QueryException qe)
		{
			response = false;
		}
		return response;
	};

	public boolean loadHistoricalOrders( )
	{

		boolean response = true;
		/*
		 * Vector result = new Vector(); Hashtable aux = new Hashtable(); String
		 * sql = "SELECT pedi_id,pedi_fecha " + "FROM pedido " + "ORDER BY
		 * pedi_fecha DESC;";
		 * 
		 * try{ result = SQLUtilities.query(sql); for(int i=0;i
		 * <result.size();i++){ aux = (Hashtable)result.elementAt(i);
		 * this.orders.put((Integer)aux.get("pedi_id"),new
		 * Order(((Integer)aux.get("pedi_id")).intValue())); }
		 * }catch(QueryException qe){ response = false; }
		 */
		return response;

	}

	/**
	 * Consultor para el atributo orders.
	 * 
	 * @return Valor del atributo orders.
	 */
	public Vector getOrders( )
	{
		return orders;
	}

	/**
	 * Modificador para el atributo orders.
	 * 
	 * @param orders
	 *            Nuevo valor del atributo orders.
	 */
	public void setOrders( Vector orders )
	{
		this.orders = orders;
	}

	public static void main( String[] args )
	{
		OrderList ol = new OrderList(14335210, "Minorista", new Date(0), new Date(0));
		System.out.println(ol.getOrders());
	}
}