
package ibase.webitm.ejb.dis;
import ibase.webitm.utility.*;
import ibase.utility.CommonConstants;
import ibase.webitm.ejb.*;
import ibase.system.config.*;
import java.rmi.RemoteException;
import java.text.*;
import java.util.*;
import java.sql.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.ejb.*;
import javax.naming.InitialContext;
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import ibase.webitm.ejb.mfg.ExplodeBom;
import javax.ejb.Stateless; // added for ejb3

@Stateless // added for ejb3


public class GenDistIssuePrc extends ProcessEJB //implements SessionBean
{
	GenericUtility genericUtility = GenericUtility.getInstance();
	ITMDBAccessEJB itmDBAccessEJB = new ITMDBAccessEJB();
	//ArrayList itemQtyList = new ArrayList();
	StringBuffer failMsg = null;
	/*public void ejbCreate() throws RemoteException, CreateException
	{
		//System.out.println("Create Method Called....");
	}
	public void ejbRemove()
	{
	}
	public void ejbActivate()
	{
	}
	public void ejbPassivate()
	{
	}*/
	public String process() throws RemoteException,ITMException
	{
		return "";
	}
	public String process(String xmlString, String xmlString2, String windowName, String xtraParams) throws RemoteException,ITMException
	{

		Document dom = null;
		String retStr = "";
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		CreateDistIssue createDistIss = null;
		DistOrdRec rec = null;
		
		String excpMsg = null;
		String sql = "";
		String retString =  null;
		String errCode = "";
		String errMsgStr = null;
		String distOrdFrom = null;
		String distOrdTo = null;
		String fromDateStr = null;
		String toDateStr = null;
		
		Timestamp fromDate = null;
		Timestamp toDate = null;
		String resultStr = null;
		
		ArrayList distOrderList = null;
		
		Connection conn = null;

		StringBuffer comXmlString = new StringBuffer("<Root>");
		String clubRequired=""; 
		String club="";
		String dOrder="";
		boolean isStockExist=false;
		String  siteCode="";
		String siteCodeDlv="";
		String orderType="";
		String locType="";
		HashMap<String, ArrayList<DistOrderClubBean>> hm = new HashMap<String,ArrayList<DistOrderClubBean>>();

		//System.out.println("xmlString[process]::::::::::;;;"+xmlString);
		//System.out.println("xmlString2[process]::::::::::;;;"+xmlString2);
		//System.out.println("windowName[process]::::::::::;;;"+windowName);
		//System.out.println("xtraParams[process]:::::::::;;;"+xtraParams);
		try
		{
			if(xmlString != null && xmlString.trim().length()!=0)
			{
				dom = genericUtility.parseString(xmlString);
			}
		}
		catch (Exception e)
		{
			//System.out.println("Exception PrcEJB :process(String xmlString, String xmlString2, String windowName, String xtraParams):" + e.getMessage() + ":");
			e.printStackTrace();
			excpMsg = e.getMessage();
		}
		try
		{
			 ConnDriver connDriver = new ConnDriver();
			 conn = connDriver.getConnectDB( "DriverITM" );
			 connDriver = null;
			 conn.setAutoCommit( false );
			 
			 createDistIss = new CreateDistIssue();
			 distOrderList = new ArrayList();
			 
			 failMsg = new StringBuffer( "" );
			 
			 distOrdFrom = genericUtility.getColumnValue( "dist_order__fr", dom );
			 distOrdTo = genericUtility.getColumnValue( "dist_order__to", dom );
			 fromDateStr = genericUtility.getColumnValue( "order_date__fr", dom );
			 toDateStr = genericUtility.getColumnValue( "order_date__to", dom );
			 fromDateStr = genericUtility.getValidDateString( fromDateStr, genericUtility.getApplDateFormat(), genericUtility.getDBDateFormat() );
			 fromDate = java.sql.Timestamp.valueOf( fromDateStr + " 00:00:00.0" );
			 //System.out.println( "fromDate..............." + fromDate );
			 toDateStr = genericUtility.getValidDateString( toDateStr, genericUtility.getApplDateFormat(),genericUtility.getDBDateFormat());
			 toDate =java.sql.Timestamp.valueOf( toDateStr + " 00:00:00.0");
			 //System.out.println( "toDate..............." + toDate);
             
			 // changes done by ManojSharma  4/Apr/12
             clubRequired=genericUtility.getColumnValue( "club", dom );
             if(clubRequired.equalsIgnoreCase("N"))
			 {	
			
            	sql = "SELECT DIST_ORDER, SITE_CODE "
			        + " FROM DISTORDER "
			        + " WHERE DIST_ORDER >= '" + distOrdFrom + "' "
				    + " AND DIST_ORDER <= '" + distOrdTo + "' "
				    + "	AND CONFIRMED = 'Y' "
				    + "	AND	STATUS <> 'C' "
				    + " AND ORDER_DATE between ? AND ? ";
				   
				//System.out.println("sql..............."+sql);
				pstmt = conn.prepareStatement(sql);
				pstmt.setTimestamp( 1, fromDate );
			    pstmt.setTimestamp( 2, toDate );
				rs = pstmt.executeQuery();
				while( rs.next() )
				{
					rec = new DistOrdRec();
					
					rec.distOrder = rs.getString( "DIST_ORDER" );
					rec.siteCode = rs.getString( "SITE_CODE" );
					distOrderList.add( rec );
				}
			
				rs.close();
				rs = null;
				pstmt.close();
				pstmt = null;
				
				int distOrderListLen = distOrderList.size();
				
				resultStr = null;
				for( int distIdx = 0; distIdx < distOrderListLen; distIdx++ )
				{
					rec = ( DistOrdRec ) distOrderList.get( distIdx );
					if( isStockExist( rec.distOrder, conn ) )
					{
						resultStr = createDistIss.createDistIssue( rec.siteCode, "<Root><TranID>" + rec.distOrder + "</TranID></Root>", xtraParams, conn );
						if( resultStr != null && !( resultStr.indexOf( "Success" ) > -1 ) )
						{
							break;
						}
					}
				}
			}
             //added else part by ManojSharma for adding logic for clubbing dist_order Req.Id DI1ISUN005
			else  
			{
				 sql=" SELECT D.DIST_ORDER,D.LINE_NO AS LINE_NO,D.TRAN_ID__DEMAND,D.ITEM_CODE AS ITEM_CODE,D.QTY_ORDER AS QTY_ORDER,D.QTY_CONFIRM AS QTY_CONFIRM,"
					+" D.QTY_RECEIVED AS QTY_RECEIVED,D.QTY_SHIPPED AS QTY_SHIPPED,D.DUE_DATE AS DUE_DATE,D.TAX_CLASS AS TAX_CLASS,D.TAX_CHAP AS TAX_CHAP,D.TAX_ENV AS TAX_ENV,D.UNIT AS UNIT,ITEM.DESCR AS ITEM_DESCR,"
					+" D.SALE_ORDER AS SALE_ORDER,D.LINE_NO__SORD AS LINE_NO__SORD,D.RATE AS RATE,D.QTY_RETURN AS QTY_RETURN,D.RATE__CLG AS RATE__CLG,D.DISCOUNT AS DISCOUNT,D.REMARKS AS REMARKS,D.TOT_AMT AS TOT_AMT,D.TAX_AMT AS TAX_AMT,"
					+" D.NET_AMT AS NET_AMT,D.OVER_SHIP_PERC AS OVER_SHIP_PERC,SPACE(300) AS QTY_DETAILS,D.UNIT__ALT AS UNIT__ALT,D.CONV__QTY__ALT AS CONV__QTY__ALT,"
					+" D.QTY_ORDER__ALT AS QTY_ORDER__ALT,D.SHIP_DATE AS SHIP_DATE,D.PACK_INSTR AS PACK_INSTR ,"
					+" ( CASE WHEN ITEM.DEPT_CODE__ISS IS NULL then ' ' else ITEM.DEPT_CODE__ISS END ) AS DEPT_CODE, "
					+" H.AVALIABLE_YN AS AVALIABLE_YN, H.TRAN_TYPE AS TRAN_TYPE,ITEM.LOC_TYPE LOC_TYPE,H.SITE_CODE SITE_CODE,H.SITE_CODE__DLV,H.ORDER_TYPE  "
					+" FROM DISTORDER_DET  D,ITEM  ITEM, DISTORDER H "
					+" WHERE D.DIST_ORDER = H.DIST_ORDER "
					+" AND D.ITEM_CODE = ITEM.ITEM_CODE "
					+" AND H.DIST_ORDER     >= '" + distOrdFrom + "' and H.DIST_ORDER<='" + distOrdTo + "'"
					+" AND ORDER_DATE between ? AND ? "
					+" AND CONFIRMED = 'Y' "
					+" AND	STATUS <> 'C' "
					+" ORDER BY item.dept_code__iss ASC,"   //added by rajendra on 02/09/08
					+" D.LINE_NO ASC ";
				pstmt = conn.prepareStatement(sql);
				pstmt.setTimestamp( 1, fromDate );
			        pstmt.setTimestamp( 2, toDate );
				rs = pstmt.executeQuery();
				while( rs.next() )
				{
				    dOrder=rs.getString("DIST_ORDER");
				    distOrderList.add(dOrder);
				    siteCode = rs.getString("SITE_CODE");
				    siteCodeDlv = rs.getString("SITE_CODE__DLV");
				    orderType = rs.getString("ORDER_TYPE");
				    locType = rs.getString("LOC_TYPE");
				    
				    if (siteCode == null ) siteCode ="";
				    if (siteCodeDlv == null ) siteCodeDlv ="";
				    if (locType == null ) locType ="";
				    if (orderType == null ) orderType ="";

				    if((siteCode.length()>0) && (siteCodeDlv.length()>0 ) && (orderType.length() >0) && (locType.length() >0))
					{
						club = siteCode.trim()+","+siteCodeDlv.trim()+","+orderType.trim()+","+locType.trim();
					}
					else
					{
						club = siteCode+","+siteCodeDlv+","+orderType+","+locType;
					}
					
				    DistOrderClubBean db = new DistOrderClubBean();
					db.setSiteCode(siteCode);
					db.setTranType(rs.getString("TRAN_TYPE"));
					db.setAvailableYn(rs.getString("AVALIABLE_YN"));
					db.setDeptCode(rs.getString("DEPT_CODE"));
					db.setLineNo(rs.getInt("LINE_NO"));
					db.setUnit(rs.getString("UNIT"));
					db.setUnitAlt(rs.getString("UNIT__ALT"));
					db.setItemCode(rs.getString("ITEM_CODE"));
					db.setQtyConfirm(rs.getDouble("QTY_CONFIRM"));
					db.setQtyShipped(rs.getDouble("QTY_SHIPPED"));
					db.setDiscount(rs.getDouble("DISCOUNT"));
					db.setDistOrdNo(dOrder);
					ArrayList<DistOrderClubBean> inputList =new ArrayList<DistOrderClubBean>();
					inputList.add(db);
					System.out.println("The content of arraylist is: " + inputList);
			
					ArrayList<DistOrderClubBean> clubList =new ArrayList<DistOrderClubBean>();
					if (hm.containsKey(club))
					{	
						clubList= hm.get(club);
						clubList.add(db);
						hm.put(club,clubList);
					}
					else
					{
						hm.put(club,inputList);
					}
					System.out.println("The size of hm is:"+hm.size());
					System.out.println("printing hm:"+hm);
					
				} // end of while 
				
				for(int i=0;i<distOrderList.size();i++)
				{
					dOrder=(String) distOrderList.get(i);
					if(!isStockExist( dOrder, conn ) )
					{
						isStockExist=false;
						break;
					}
					else
					{
						isStockExist=true;
					}

				} // end of for 
				System.out.println("is stock exist::"+isStockExist);
				if(isStockExist==true)
				{
					Set<Map.Entry<String, ArrayList<DistOrderClubBean>>> set = hm.entrySet();
					for (Map.Entry<String, ArrayList<DistOrderClubBean>> me : set)
					{
						ArrayList<DistOrderClubBean> distOrdBean = me.getValue();	
						resultStr = createDistIss.createDistIssue( "",distOrdBean,xtraParams, conn );
						if( resultStr != null && !( resultStr.indexOf( "Success" ) > -1 ) )
						{
							break;
						}
					}
				}
				else
				{
					//chandni error stock does not exist
					errMsgStr = itmDBAccessEJB.getErrorString("","VMILOTV","BASE");
				}
				if( resultStr != null && !( resultStr.indexOf( "Success" ) > -1 ) )
				{
					//msalam on 220609 for showing actual error coming from createDistIssue.
					//retString = "VTFAIL";
					retString = resultStr;
				}
				else
				{
					System.out.println("in else after create dist iss exp ::  "+retString);	
					//commented for test on 220609
					//retString = null;
				}
			} // end of else ended by ManojSharma  
		}
		catch(ITMException itme)
		{
		   System.out.println("returning in itme ::  "+retString);
		   retString = "ERROR";
		   excpMsg = itme.getMessage();
		   //System.out.println("Exception in...."+e.getMessage());
		   itme.printStackTrace();
		}
	   	catch(Exception e)
		{
		   //System.out.println("returning in exp ::  "+retString);
		   retString = "ERROR";
		   excpMsg = e.getMessage();
		   //System.out.println("Exception in...."+e.getMessage());
		   e.printStackTrace();
		}
		finally
		{
			try
			{
				if (createDistIss != null)
				{
					//createDistIss.clear();
					createDistIss = null;
				}
				if (distOrderList != null)
				{
					//distOrderList.clear();
					distOrderList = null;
				}
				//System.out.println( "retString :: " + retString );
				if ( retString == null || retString.trim().length() == 0 )
				{
					conn.commit();
					//System.out.println("commiting connection.............");
					retString = itmDBAccessEJB.getErrorString("","VTDESPCONF","BASE");
					//errString =	itmDBAccessEJB.getErrorString("", errString, "");
					
					if( failMsg != null && failMsg.toString().trim().length() > 0 )
					{	
						String begPart = retString.substring( 0, retString.indexOf("<trace>") + 7 );
						String endPart = retString.substring( retString.indexOf("</trace>"));
						String mainStr = begPart + "Following Dist Orders can not be processded due to \n unavailability of stock \n or unconfirmed Distribution Issue already exist :\n" + failMsg.toString() + endPart;
						retString = mainStr;
						begPart =null;
						endPart =null;
						mainStr =null;
					}
				}
				else
			    {
					conn.rollback();
					//System.out.println("connection rollback.............");
					//msalam on 220609 for showing actual error coming from createDistIssue
					//System.out.println( "excpMsg in else :: " + excpMsg );
					//retString = itmDBAccessEJB.getErrorString( "", "VTDESNCONF", "BASE" );
					errMsgStr = itmDBAccessEJB.getErrorString( "", "VTDESNCONF", "BASE" );
					//end by msalam on 220609
				}
				if( rs != null )
				{
					rs.close();
				}
				rs = null;
				if (pstmt != null)
				{
					pstmt.close();
				}
				if(conn != null)
				{
					conn.close();
					conn = null;
				}
			}
			catch(Exception e)
			{
			   //System.out.println("Error In closing connection::==> "+e);
			   excpMsg = e.getMessage();
		       e.printStackTrace();
			}
		}
		if( excpMsg != null && excpMsg.trim().length() > 0 )
		{
			String begPart = retString.substring( 0, retString.indexOf("<trace>") + 7 );
			String endPart = retString.substring( retString.indexOf("</trace>"));
			String mainStr = begPart + "Following Exception has occured\n" + ( excpMsg == null ? "" : excpMsg ) + endPart;
			retString = mainStr;
			begPart =null;
			endPart =null;
			mainStr =null;		
		}else if( errMsgStr != null && errMsgStr.trim().length() > 0 )
		{
			String errStr = retString.substring( retString.indexOf("<trace>") + 7, retString.indexOf("</trace>") );
			
			String begPart = errMsgStr.substring( 0, errMsgStr.indexOf("<trace>") + 7 );
			String endPart = errMsgStr.substring( errMsgStr.indexOf("</trace>"));
			String mainStr = begPart + errStr + endPart;
			retString = mainStr;

			begPart =null;
			endPart =null;
			mainStr =null;				
		}
		
		//System.out.println("returning from     "+retString);
	    return (retString);
	}
	private boolean isStockExist( String distOrder, Connection conn ) throws Exception
	{
		String locCodeDamaged = null;
		String res = "";
		String sql = null;
		int count = 0;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		String distOrderIss = null;
		String tranIdIss = null;
		String confirmed = null;
		double qtyOrder = 0.0;
		double quantity = 0.0;
		String availableYN = null;
		// 28/05/09 manoharan avialable_yn added
		sql = "SELECT LOC_CODE__DAMAGED, AVALIABLE_YN "
			+ " FROM DISTORDER WHERE DIST_ORDER = '"+distOrder+"' ";
		pstmt= conn.prepareStatement( sql );
		rs = pstmt.executeQuery();
		if ( rs.next() )
		{
			locCodeDamaged = rs.getString( "LOC_CODE__DAMAGED" );
			//System.out.println("locCodeDamaged :"+locCodeDamaged);

			if( locCodeDamaged == null )
			{
				locCodeDamaged = "";
			}
			// 28/05/09 manoharan available_yn added
			availableYN = rs.getString( "AVALIABLE_YN" );
			if( availableYN == null )
			{
				availableYN = "Y";
			}
			// end 28/05/09 manoharan available_yn added
		}
		rs.close();
		rs = null;
		pstmt.close();
		pstmt = null;	
		
		if ( locCodeDamaged != null && locCodeDamaged.trim().length() > 0 )
		{
			StringTokenizer st = new StringTokenizer( locCodeDamaged, "," );
			while ( st.hasMoreTokens() )
			{
				res = res + "'" + st.nextToken() + "',";
			}
			res = res.substring( 0, res.length() - 1 );
			//System.out.println("res ::" + res);
			locCodeDamaged = res;
			//System.out.println("locCodeDamaged After String Tockenized ::"+locCodeDamaged);
		}
		
		sql = "SELECT count( 1 ) cnt"
			+"	FROM STOCK A, INVSTAT B, LOCATION C "
			+" WHERE C.INV_STAT = B.INV_STAT "
			+"	AND A.LOC_CODE = C.LOC_CODE "
			+"	AND ( A.ITEM_CODE, A.SITE_CODE ) in ( SELECT D.item_code, H.SITE_CODE__SHIP "
			+"	FROM DISTORDER H, DISTORDER_DET  D "
			+"	WHERE h.dist_order = d.dist_order "
			+"	and D.DIST_ORDER = '" + distOrder + "' ) "   
			+"	AND B.AVAILABLE = ? " 
			+"	AND B.USABLE = ? "
			+"	AND B.STAT_TYPE <> 'S' "
			+"	AND A.QUANTITY - A.ALLOC_QTY > 0 "
			+" 	AND NOT EXISTS (SELECT 1 FROM INV_RESTR I WHERE I.INV_STAT = B.INV_STAT AND I.REF_SER = 'D-ISS') ";
		
		if( locCodeDamaged != null && locCodeDamaged.trim().length() > 0 )
		{
			sql = sql + " AND A.LOC_CODE IN (" + locCodeDamaged + ")";
		}
		
		pstmt= conn.prepareStatement( sql );
		// 28/05/09 manoharan available_yn dynamic bind
		pstmt.setString(1,availableYN);
		pstmt.setString(2,availableYN);
		rs = pstmt.executeQuery();
		if ( rs.next() )
		{
			count = rs.getInt( "cnt" );
		}
		rs.close();
		rs = null;
		pstmt.close();
		pstmt = null;	
		
		if( count == 0 )
		{
			failMsg.append( distOrder + " Stock does not exist!\n" );
		}
		
		int distIssCount = 0;
		/* sql changed as it was not allowing partial processing msalam on 230609
		sql = " select h.dist_order, h.tran_id, h.confirmed, DH.QTY_ORDER, D.QUANTITY "
			+" from DISTORD_ISS H, distord_Issdet D, DISTORDER_DET DH "
			+" where H.dist_order = '" + distOrder + "' "
			+"  AND H.TRAN_ID = D.TRAN_ID "
			+"  AND D.DIST_ORDER = DH.DIST_ORDER "
			+"  AND D.LINE_NO_DIST_ORDER = DH.LINE_NO ";
		*/
		// 21/04/10 manoharan 1st check unconfirmed issues
		sql = " select count(1) as cnt "
			+"	from DISTORD_ISS "
			+"  where dist_order = ? "
			+ " and (case when confirmed is null then 'N' else confirmed end) = 'N' ";
			
		pstmt= conn.prepareStatement( sql );
		pstmt.setString( 1, distOrder );
		
		rs = pstmt.executeQuery();
		
		if ( rs.next() )
		{
			distIssCount = rs.getInt( "cnt" );
		}
		rs.close();
		rs = null;
		pstmt.close();
		pstmt = null;
		sql = null;
		boolean issToBeGenerated = true;
		if (distIssCount > 0 )
		{
			issToBeGenerated = false;
			failMsg.append( distOrder + " Unconfirmed Issue Exists!\n" );
		}
		else
		{

			/* 21/04/10 manoharan wrong logic for pending order checking
			sql = " select h.confirmed, D.QTY_ORDER AS QTY_ORDER, D.QUANTITY AS QUANTITY"
				+"	from DISTORD_ISS H, "
				+"			( select sum( DH.QTY_ORDER ) QTY_ORDER, sum( D.QUANTITY )  QUANTITY "
				+"					from DISTORD_ISS H, distord_Issdet D, DISTORDER_DET DH "
				+"			 where H.dist_order = ? " 
				+"					  AND H.TRAN_ID = D.TRAN_ID " 
				+"					  AND D.DIST_ORDER = DH.DIST_ORDER "
				+"					  AND D.LINE_NO_DIST_ORDER = DH.LINE_NO "
				+"			  ) d "                                       
				+"  where H.dist_order = ? ";
				//+"   AND H.TRAN_ID = D.TRAN_ID ";
			*/
			sql = " select sum(ord_qty) ord_qty, sum(iss_qty) iss_qty from ( "
				+ " select d.line_no, d.qty_order ord_qty, "
				+ " (select sum(id.quantity) from distord_issdet id where id.dist_order =  d.dist_order "
				+ " and id.line_no_dist_order = d.line_no ) iss_qty "
				+ " from distorder_det d "
				+ " where d.dist_order = ? ) " ;
			
			pstmt= conn.prepareStatement( sql );
			pstmt.setString( 1, distOrder );
			//pstmt.setString( 2, distOrder );
			
			rs = pstmt.executeQuery();
			
			if ( rs.next() )
			{
				//confirmed = rs.getString( "confirmed" );
				qtyOrder = rs.getDouble( "ord_qty" );
				quantity = rs.getDouble( "iss_qty" );
			}
			rs.close();
			rs = null;
			pstmt.close();
			pstmt = null;
			sql = null;
			
			if( qtyOrder - quantity <= 0 ) 
			{
				issToBeGenerated = false;
				failMsg.append( distOrder + " All Quantity Issued.!\n" );			
			} 
		}
		// end 21/04/10 manoharan 1st check unconfirmed issues
		
		
		//check for unconfirmed dist order not to be processed
		int unConf = 0;
		sql = "SELECT count( 1 ) cnt "
			   +" FROM DISTORDER "
			   +" WHERE DIST_ORDER = '" + distOrder + "' "
			   +"	AND ( CONFIRMED = 'N' OR STATUS = 'C' ) ";
		pstmt= conn.prepareStatement( sql );
		rs = pstmt.executeQuery();
		if ( rs.next() )
		{
			unConf = rs.getInt( "cnt" );
		}
		rs.close();
		rs = null;
		pstmt.close();
		pstmt = null;
		sql = null;
		if( unConf > 0 )
		{
			failMsg.append( distOrder + " Unconfirmed Dist order or closed!\n" );
		}
		// end 
		System.out.println("inside isstock count:"+count+"issToBeGenerated:"+issToBeGenerated+"unConf:"+unConf);
		return count > 0 && issToBeGenerated && unConf == 0;
	}
	private class DistOrdRec
	{
		String distOrder = null;
		String siteCode = null;
	}
}
