/*
 * PriceScale.java
 *
 * Created on 12 de agosto de 2004, 15:19 
 */

package com.fenalco.entities;

import java.util.Hashtable;
import java.util.Vector;

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

/**
 * Esta clase representa la tabla escala_precio_producto de la base de datos y
 * encapsula cada una de las operaciones que sobre esta se puedan realizar :
 * inserción, actualización, eliminación, consulta. De forma lógica hace
 * referencia a la escala de precios que esta asociada con el producto de un
 * proveedor.
 * 
 * @author Mario Linares Vásquez
 */

public class PriceScale
{
	// TODO: queda pendiente modificar la tabla escala_precio_producto
	// dependiendo
	// de la información que venga de iac

	/**
	 * Identificador de la comunidad para la cual aplica esta escala de precios
	 */
	private int communityId;

	/**
	 * Identificador del producto-proveedor para el cual aplica esta escala
	 */
	private int supplierProductId;

	/**
	 * Hashtable de la escala de precios. Este Hashtable está construido de la
	 * siguiente forma, la llave es el id de la tabla y el value un vector cuyos
	 * valores son: - id del rango (tabla escala_precio_producto) - cantidad
	 * minima - cantidad maxima - precio
	 */
	private Vector values;

	/**
	 * Constructor por omisión de la clase
	 */
	public PriceScale( )
	{
		values = new Vector();
	}

	/**
	 * Constructor que recibe el identificador del producto-proveedor y el de la
	 * comunidad para cargar todas las escalas de precios asociadas con estos
	 * datos.
	 * 
	 * @param supplierProduct
	 *            int que representa el id de la relación producto-proveedor a
	 *            la cual esta asociada la escala
	 * @param community
	 *            representa la comunidad para la cual aplica la escala
	 */
	public PriceScale( int supplierProduct, int community)
	{
		this();
		loadData(supplierProduct, community);
	}

	/**
	 * Carga la información de la base de datos a partir del producto-proveedor
	 * y la comunidad.
	 * 
	 * @return boolean que representa el exito del proceso de carga de los datos
	 * @param supplierProduct
	 *            int que representa el id de la relación producto-proveedor a
	 *            la cual esta asociada la escala
	 * @param community
	 *            comunidad para la que aplica la escala de precios
	 */
	public boolean loadData( int supplierProduct, int community )
	{
		boolean respuesta = false;

		supplierProductId = supplierProduct;
		communityId = community;

		String sql = "SELECT esca_prec_prod_id, esca_prec_prod_minimo, esca_prec_prod_maximo"
				+ ", esca_prec_prod_precio FROM escala_precio_producto WHERE "
				+ "comu_id="
				+ community
				+ " AND "
				+ "prod_prov_id="
				+ supplierProductId + " ORDER BY esca_prec_prod_minimo ASC;";
		try
		{
			Vector res = SQLUtilities.query(sql);
			for( int i = 0; i < res.size(); i++ )
			{
				Hashtable datos = (Hashtable) res.elementAt(i);
				Vector rango = new Vector();
				Integer idesc = (Integer) datos.get("esca_prec_prod_id");
				rango.addElement(idesc);
				rango.addElement(datos.get("esca_prec_prod_minimo"));
				rango.addElement(datos.get("esca_prec_prod_maximo"));
				rango.addElement(datos.get("esca_prec_prod_precio2"));

				//values.put( idesc, rango );
				values.addElement(rango);
			}
		}
		catch (Exception e)
		{
			respuesta = false;
		}

		return respuesta;
	}

	/**
	 * Este método guarda los atributos de la escala de precios en la base de
	 * datos. Se debe usar solo cuando se desee crear una nueva escala de
	 * precios en la escala. Para almacenar los datos en la tabla
	 * escala_precio_producto debe construir una consulta SQL de tipo <B>insert
	 * </B> y la adiciona a la transacción con el método <CODE>addSql</CODE>
	 * 
	 * @return boolean que representa el exito del proceso de inserción
	 * @param transaction
	 *            la transacción que se está ejecutando
	 */
	public boolean saveData( Transaction transaction )
	{
		return true;
	}

	/**
	 * Realiza una consulta SQL de tipo update con el fin de actualizar los
	 * campos de la escala de precios modificados a través de los métodos setter
	 * o el método addToScale. Para actualizar los datos en la tabla
	 * escala_precio_producto debe construir una consulta SQL de tipo <B>update
	 * </B>y la adiciona a la transacción con el método <CODE>addSql</CODE>
	 * 
	 * @return boolean que representa el exito del proceso de actualización
	 * @param transaction
	 *            la transacción que se está ejecutando
	 */
	public boolean update( Transaction transaction )
	{
		/*
		 * Enumeration e = values.elements();
		 * 
		 * while( e.hasMoreElements() ) { Vector v = ( Vector )e.nextElement();
		 * String sql = "UPDATE escala_precio_producto SET " +
		 * "esca_prec_prod_minimo=" + v.elementAt( 1 ) + ", " +
		 * "esca_prec_prod_maximo=" + v.elementAt( 2 ) + ", " +
		 * "esca_prec_prod_precio=" + v.elementAt( 3 ) + " " + "WHERE
		 * esca_prec_prod_id=" + v.elementAt( 0 ) + ";";
		 * transaction.addSql(sql); }
		 */
		int i = 0;
		while( i < this.values.size() )
		{
			Vector v = (Vector) this.values.elementAt(i);
			String sql = "UPDATE escala_precio_producto SET "
					+ "esca_prec_prod_minimo=" + v.elementAt(1) + ", "
					+ "esca_prec_prod_maximo=" + v.elementAt(2) + ", "
					+ "esca_prec_prod_precio=" + v.elementAt(3) + " "
					+ "WHERE esca_prec_prod_id=" + v.elementAt(0) + ";";
			transaction.addSql(sql);
			i++;
		}
		return true;
	}

	/**
	 * Realiza una consulta SQL de tipo delete con el fin de eliminar la escala
	 * de la base de datos cuando se creo la instancia con el constructor que
	 * recibe el id como parámetro.Para eliminar los datos en la tabla
	 * escala_precio_producto debe construir una consulta SQL de tipo
	 * <B>deletete </B> y la adiciona a la transacción con el método <CODE>
	 * addSql</CODE>
	 * 
	 * @return boolean que representa el exito del proceso de borrado
	 * @param transaction
	 *            la transacción que se está ejecutando
	 */
	public boolean delete( Transaction transaction )
	{
		/*
		 * Enumeration e = values.keys(); while( e.hasMoreElements() ) { int i = ( (
		 * Integer )e.nextElement() ).intValue(); String sql = "DELETE FROM
		 * escala_precio_producto WHERE esca_prec_prod_id="+ i + ";";
		 * transaction.addSql(sql); }
		 */

		int i = 0;
		while( i < this.values.size() )
		{
			Vector v = (Vector) this.values.elementAt(i);
			int id = ((Integer) v.elementAt(0)).intValue();
			String sql = "DELETE FROM escala_precio_producto WHERE esca_prec_prod_id="
					+ id + ";";
			transaction.addSql(sql);
			i++;
		}
		return true;
	}

	/**
	 * Este método permite eliminar una entrada de la escala de precios, recibe
	 * el identificador de la entrada y una transacción.
	 * 
	 * @param scaleId
	 *            Identificador de la entrada de la escala de precios
	 * @param transaction
	 *            Transacción que se está ejecutando
	 * @return Valor booleano que indica si la operación tuvo éxito o no.
	 */
	public boolean deleteRow( int scaleId, Transaction transaction )
	{

		//this.values.remove(new Integer(scaleId));
		int i = 0;
		while( i < this.values.size() )
		{
			Integer key = (Integer) ((Vector) this.values.elementAt(i))
					.elementAt(0);
			if( key.intValue() == scaleId )
			{
				this.values.remove(i);
				break;
			}
			i++;
		}
		String sql = "DELETE FROM escala_precio_producto WHERE esca_prec_prod_id="
				+ scaleId + ";";
		transaction.addSql(sql);

		return true;

	}

	/**
	 * Este método agrega un rango nuevo a la escala de precios. Para tal efecto
	 * debe ejecutar una consulta insert sobre la tabla escala_precio_producto
	 * con los parámetros <CODE>minQuantity</CODE>,<CODE>maxQuantity
	 * </CODE>,<CODE>discount</CODE> con el mismo <CODE>supplierProductId
	 * </CODE> de la clase. Luego debe llamar el método <CODE>loadData</CODE>
	 * para actualizar el Hashtable de la clase
	 * 
	 * @param minQuantity
	 *            cantidad mínima del rango
	 * @param maxQuantity
	 *            cantidad máxima del rango
	 * @param price
	 *            precio aplicable sobre el rango
	 * @return boolean que repreenta el exito de la inserción
	 */
	public boolean addToScale( int minQuantity, int maxQuantity, double price )
	{
		try
		{
			//int i = SQLUtilities.getNextId( "escala_precio_producto", "");
			int i = this.hashCode();

			String sql = "INSERT INTO escala_precio_producto (esca_prec_prod_id, comu_id, "
					+ "prod_prov_id, esca_prec_prod_minimo, esca_prec_prod_maximo, "
					+ "esca_prec_prod_precio) VALUES("
					+ i
					+ ", "
					+ communityId
					+ ", "
					+ supplierProductId
					+ ", "
					+ minQuantity
					+ ", "
					+ maxQuantity + ", " + price + ");";
			try
			{
				SQLUtilities.execute(sql);
				Vector v = new Vector();
				Integer ide = new Integer(i);

				v.addElement(ide);
				v.addElement(new Integer(minQuantity));
				v.addElement(new Integer(maxQuantity));
				v.addElement(new Double(price));
				values.addElement(v);

				return true;
			}
			catch (Exception e)
			{
				return false;
			}
		}
		catch (Exception ex)
		{
			return false;
		}
	}

	public int getNextMin( )
	{
		int nextMin = -1;
		/*
		 * Enumeration e = this.values.keys(); Vector aux = new Vector();
		 * while(e.hasMoreElements()){ aux =
		 * (Vector)this.values.get(e.nextElement());
		 * if(((Integer)aux.elementAt(2)).intValue() > nextMin ){ nextMin =
		 * ((Integer)aux.elementAt(2)).intValue(); } }
		 */

		int i = 0;
		while( i < this.values.size() )
		{
			Vector aux = (Vector) this.values.elementAt(i);
			if( ((Integer) aux.elementAt(2)).intValue() > nextMin )
			{
				nextMin = ((Integer) aux.elementAt(2)).intValue();
			}
			i++;
		}

		if( nextMin == -1 )
		{
			nextMin = 0;
		}
		return nextMin + 1;
	}

        
        public int getMaxValue(){
        
            Vector values = this.getValues( );
            int max = 0;
            for( int i = 0; i < values.size( ); i++ )
            {
                    int tm = ( ( Integer )( ( Vector )values.elementAt( i ) ).elementAt( 2 ) )
                                    .intValue( );
                    if( tm > max )
                    {
                            max = tm;
                    }
            }
            
            return max;
        }
	/* :x */
	public static boolean existScale( int supplierProductId, int supplierId )
	{
		boolean exist = false;
		Vector communitiesIds = DataAccess.communityIds(supplierId);
		if( communitiesIds.size() > 0 )
		{

			for( int i = 0; i < communitiesIds.size(); i++ )
			{
				PriceScale ps = new PriceScale(supplierProductId,
						((Integer) communitiesIds.elementAt(i)).intValue());
				if( ps.getValues().size() > 0 )
				{
					exist = true;
					break;
				}
			}

		}
		else
		{

			exist = false;

		}

		return exist;
	}
        
        
        public double getValue(int quantity){
            double value = -1;
            double temp = 0;
            int i = 0;
            boolean flag = true;
            while( flag && i < this.values.size() )
            {
                    Vector aux = (Vector) this.values.elementAt(i);
                    System.out.println("quantity-->"+quantity+" inf-->"+((Integer) aux.elementAt(1)).intValue()+" sup-->"+((Integer) aux.elementAt(2)).intValue());
                    if(  (quantity >=  ((Integer) aux.elementAt(1)).intValue()) && (quantity <=  ((Integer) aux.elementAt(2)).intValue()) )
                    
                    {
                            flag = false;
                            value = ((Double) aux.elementAt(3)).doubleValue();
                            
                    }
                    temp = ((Double) aux.elementAt(3)).doubleValue();
                    i++;
            }
            
            
            return (value ==- 1 ? temp : value);
            
        }
        

	/**
	 * Getter for property communityId.
	 * 
	 * @return Value of property communityId.
	 */
	public int getCommunityId( )
	{
		return communityId;
	}

	/**
	 * Setter for property communityId.
	 * 
	 * @param communityId
	 *            New value of property communityId.
	 */
	public void setCommunityId( int communityId )
	{
		this.communityId = communityId;
	}

	/**
	 * Getter for property supplierProductId.
	 * 
	 * @return Value of property supplierProductId.
	 */
	public int getSupplierProductId( )
	{
		return supplierProductId;
	}

	/**
	 * Setter for property supplierProductId.
	 * 
	 * @param supplierProductId
	 *            New value of property supplierProductId.
	 */
	public void setSupplierProductId( int supplierProductId )
	{
		this.supplierProductId = supplierProductId;
	}

	/**
	 * Getter for property values.
	 * 
	 * @return Value of property values.
	 */
	public java.util.Vector getValues( )
	{
		return values;
	}

	/**
	 * Setter for property values.
	 * 
	 * @param values
	 *            New value of property values.
	 */
	public void setValues( java.util.Vector values )
	{
		this.values = values;
	}

}