package org.compiere.model;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.logging.Level;

import org.compiere.util.Ctx;
import org.compiere.util.DB;

public class MReturnPolicy extends X_M_ReturnPolicy {

	public MReturnPolicy(Ctx ctx, int M_ReturnPolicy_ID, String trxName) {
		super(ctx, M_ReturnPolicy_ID, trxName);
	}

	public MReturnPolicy(Ctx ctx, ResultSet rs, String trxName) {
		super(ctx, rs, trxName);

	}

	/**************************************************************************
	 * 	Get Lines of Return Policy for a product
	 * 	@param whereClause where clause or null (starting with AND)
	 * 	@param orderClause order clause
	 * 	@return lines
	 */
	int getProductLine (int M_Product_ID)
	{
		StringBuffer sql = new StringBuffer("SELECT M_ReturnPolicyLine_ID FROM M_ReturnPolicyLine WHERE M_ReturnPolicy_ID =? ");
		int M_ReturnPolicyLine_ID = 0;
		
		if (M_Product_ID != 0)
			sql.append("AND M_Product_ID = ?  ");
		
		PreparedStatement pstmt = null;
		try
		{
			pstmt = DB.prepareStatement(sql.toString(), get_TrxName());
			pstmt.setInt(1, getM_ReturnPolicy_ID());
			
			if (M_Product_ID != 0)
				pstmt.setInt(2, M_Product_ID);
			
			ResultSet rs = pstmt.executeQuery();
			if (rs.next())
				M_ReturnPolicyLine_ID = rs.getInt(1);				
			rs.close();
			pstmt.close();
			pstmt = null;
		}
		catch (Exception e)
		{
			log.log(Level.SEVERE, sql.toString(), e);
		}
		finally
		{
			try
			{
				if (pstmt != null)
					pstmt.close ();
			}
			catch (Exception e)
			{}
			pstmt = null;
		}
		//
		return M_ReturnPolicyLine_ID;
	}	//	getProductLine

	/**************************************************************************
	 * 	Get Lines of Return Policy for a product
	 * 	@param whereClause where clause or null (starting with AND)
	 * 	@param orderClause order clause
	 * 	@return lines
	 */
	int getProductCategoryLine (int M_Product_Category_ID)
	{
		StringBuffer sql = new StringBuffer("SELECT M_ReturnPolicyLine_ID FROM M_ReturnPolicyLine WHERE M_ReturnPolicy_ID =? ");
		int M_ReturnPolicyLine_ID = 0;
		
		if (M_Product_Category_ID != 0)
			sql.append("AND M_Product_ID IS NULL AND M_Product_Category_ID = ?  ");
		
		PreparedStatement pstmt = null;
		try
		{
			pstmt = DB.prepareStatement(sql.toString(), get_TrxName());
			pstmt.setInt(1, getM_ReturnPolicy_ID());
			
			if (M_Product_Category_ID != 0)
				pstmt.setInt(2, M_Product_Category_ID);
			
			ResultSet rs = pstmt.executeQuery();
			if (rs.next())
				M_ReturnPolicyLine_ID = rs.getInt(1);				
			rs.close();
			pstmt.close();
			pstmt = null;
		}
		catch (Exception e)
		{
			log.log(Level.SEVERE, sql.toString(), e);
		}
		finally
		{
			try
			{
				if (pstmt != null)
					pstmt.close ();
			}
			catch (Exception e)
			{}
			pstmt = null;
		}
		//
		return M_ReturnPolicyLine_ID;
	}	//	getProductCategoryLine

	/**************************************************************************
	 * 	Get Lines of Return Policy for a product
	 * 	@param whereClause where clause or null (starting with AND)
	 * 	@param orderClause order clause
	 * 	@return lines
	 */
	boolean policyHasLines ()
	{
		StringBuffer sql = new StringBuffer("SELECT count(*) FROM M_ReturnPolicyLine WHERE M_ReturnPolicy_ID =? ");
		int lineCount=0;
		
		PreparedStatement pstmt = null;
		try
		{
			pstmt = DB.prepareStatement(sql.toString(), get_TrxName());
			pstmt.setInt(1, getM_ReturnPolicy_ID());
			
			ResultSet rs = pstmt.executeQuery();
			if (rs.next())
				lineCount = rs.getInt(1);				
			rs.close();
			pstmt.close();
			pstmt = null;
		}
		catch (Exception e)
		{
			log.log(Level.SEVERE, sql.toString(), e);
		}
		finally
		{
			try
			{
				if (pstmt != null)
					pstmt.close ();
			}
			catch (Exception e)
			{}
			pstmt = null;
		}
		//
		return lineCount != 0;
	}	//	getProductLine

	public boolean checkReturnPolicy(Timestamp shipDate, Timestamp returnDate)
	{
		if(policyHasLines())
			return true;

		long timeFrame = getTimeFrame()* 24 * 60 * 60 ; // Timeframe in milliseconds
		// If timeFrame is 0, returns are not allowed
		if(timeFrame == 0)
			return false;
		
		log.fine("ShipDate : "+shipDate.toString() + " ReturnDate : "+returnDate.toString() + " TimeFrame : " +timeFrame);
		Timestamp allowedDate = new Timestamp(timeFrame * 1000 + shipDate.getTime() );
		
		log.fine("Allowed Date : "+allowedDate.toString());
		if(returnDate.after(allowedDate))
			return false;
		return true;
	}

	public boolean checkReturnPolicy(Timestamp shipDate, Timestamp returnDate, int M_Product_ID)
	{

		int M_ReturnPolicyLine_ID = getProductLine(M_Product_ID);
		if (M_ReturnPolicyLine_ID == 0)
		{
			MProduct product = new MProduct (getCtx(), M_Product_ID, get_TrxName());
			getProductCategoryLine(product.getM_Product_Category_ID());
		}
		
		long timeFrame; 
		if (M_ReturnPolicyLine_ID == 0)
			timeFrame = getTimeFrame()* 24 * 60 * 60 ; // Timeframe in milliseconds
		else
		{
			MReturnPolicyLine rpolicyLine = new MReturnPolicyLine (getCtx(), M_ReturnPolicyLine_ID, get_TrxName());
			timeFrame = rpolicyLine.getTimeFrame()* 24 * 60 * 60 ; // Timeframe in milliseconds
		}

		if(timeFrame == 0)
			return false;

		log.fine("ShipDate : "+shipDate.toString() + " ReturnDate : "+returnDate.toString() + " TimeFrame : " +timeFrame);
		Timestamp allowedDate = new Timestamp(timeFrame * 1000 + shipDate.getTime() );
		
		log.fine("Allowed Date : "+allowedDate.toString());
		if(returnDate.after(allowedDate))
			return false;
		return true;
	}
	
	/**
	 * 	Get Default MReturnPolicy
	 *	@param ctx context
	 *	@return MReturnPolicy
	 */
	public static int getDefault (Ctx ctx)
	{
		int AD_Client_ID = ctx.getAD_Client_ID();
		int rPolicy_ID = 0;
		
		PreparedStatement pstmt = null;
		String sql = "SELECT M_ReturnPolicy_ID FROM M_ReturnPolicy"
			+ " WHERE IsDefault='Y' AND IsActive='Y' AND AD_Client_ID=? ";
		try
		{
			pstmt = DB.prepareStatement (sql, null);
			pstmt.setInt (1, AD_Client_ID);
			ResultSet rs = pstmt.executeQuery ();
			if (rs.next ())
			{
				rPolicy_ID = rs.getInt(1);
			}
			rs.close ();
			pstmt.close ();
			pstmt = null;
		}
		catch (Exception e)
		{}
		
		return rPolicy_ID;
	}	//	get

}
