/********************************************************
	Title : ShipmentConf
	Date  : 01/06/2012
	Developer: Mahesh Patidar
 ********************************************************/

package ibase.webitm.ejb.wms;

import ibase.system.config.ConnDriver;
import ibase.webitm.ejb.ActionHandlerEJB;
import ibase.webitm.ejb.ITMDBAccessEJB;
import ibase.webitm.ejb.ITMDBAccessLocal;
import ibase.webitm.utility.GenericUtility;
import ibase.webitm.utility.ITMException;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.ejb.Stateless;
import javax.xml.rpc.ParameterMode;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
//Changed by sumit on 06/10/12
import org.w3c.dom.*;


@Stateless
public class ShipmentConf extends ActionHandlerEJB implements ShipmentConfLocal, ShipmentConfRemote
{
	GenericUtility genericUtility = GenericUtility.getInstance();
	public String confirm(String tranId, String xtraParam, String forcedFlag) throws RemoteException,ITMException
	{
		int cnt = 0;
		String errString = "";
		String sql = "";
		String refId = "",proNo = "",tranProNo = "";
		String lorryNo = "";
		String tranCode = "";
		String lrNo = "";
		//Changed by sumit on 28/09/12 
		String confirmed = "";
		String newErro = "";
		//Changed by sumit on 05/10/12 created ref_ser variable 
		String refSer = "", refSerNew = "";
		int noOfPallet = 0, count = 0;
		ArrayList<String> errList = new ArrayList<String>();
		Timestamp lrDate = null;
		ConnDriver connDriver = new ConnDriver();
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null; 
		PreparedStatement pstmt1 = null;
		try
		{
			conn = connDriver.getConnectDB( "DriverITM" );
			String userID = genericUtility.getValueFromXTRA_PARAMS( xtraParam, "LoginCode" );
			//Changed by sumit on 28/09/12 checking whether shipment is already confirmed or not start.
			System.out.println(" forced flag ["+forcedFlag+"]");
			ITMDBAccessLocal itmDBAccessLocal = new ITMDBAccessEJB();
			sql = "SELECT SHIPMENT.CONFIRMED, SHIPMENT.NO_PALLET, SHIP_DOCS.REF_SER " +
					" FROM SHIPMENT, SHIP_DOCS WHERE SHIPMENT.SHIPMENT_ID = ? " +
					" AND SHIP_DOCS.SHIPMENT_ID = SHIPMENT.SHIPMENT_ID";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, tranId);
			rs = pstmt.executeQuery();
			if( rs.next())
			{
				confirmed = rs.getString("CONFIRMED");
				noOfPallet = rs.getInt("NO_PALLET");
				refSer = checkNull(rs.getString("REF_SER"));
			}
			System.out.println("-- confirmed ["+confirmed+"] noOfPallet ["+noOfPallet+"] refSer ["+refSer.trim()+"]");
			rs.close();rs = null;
			pstmt.close();pstmt = null;
			
			if( "Y".equalsIgnoreCase(confirmed))
			{
				errString = itmDBAccessLocal.getErrorString("","SHIPALLCON","");
			}
			else
			{
				if( "S-DSP".equalsIgnoreCase(refSer.trim()) && "N".equalsIgnoreCase(forcedFlag))
				{
					errString = itmDBAccessLocal.getErrorString("","SDSPCONFIR","");
				}
				else
				{
					sql = "SELECT COUNT(*) as COUNT FROM SHIPMENT_CONTENT WHERE SHIPMENT_ID = ?";
					pstmt = conn.prepareStatement(sql);
					pstmt.setString(1, tranId);
					rs = pstmt.executeQuery();
					if( rs.next())
					{
						count = rs.getInt("COUNT");
					}
					rs.close();rs = null;
					pstmt.close();pstmt = null;
					if( noOfPallet != count && !("S-DSP".equalsIgnoreCase(refSer.trim())))
					{
						errString = itmDBAccessLocal.getErrorString("","NOOFPALLET","");
					}
					else
					{
						//Changed by sumit on 28/09/12 checking whether shipment is already confirmed or not end.					
						sql = "SELECT LORRY_NO,TRAN_CODE,LR_NO,LR_DATE, pro_no FROM SHIPMENT WHERE SHIPMENT_ID = ?";
						pstmt = conn.prepareStatement(sql);
						pstmt.setString(1, tranId);
						rs = pstmt.executeQuery();
						if( rs.next() )
						{
							lorryNo = rs.getString(1);
							tranCode = rs.getString(2);
							lrNo = rs.getString(3);
							lrDate = rs.getTimestamp(4);
							proNo = rs.getString(5);
						}
						rs.close();
						rs = null;
						pstmt.close();
						pstmt = null;
			
						//Changed by sumit on 28/09/12 wrong sql
						//sql = "SELECT PRONO_LASTe FROM transporter WHERE tran_code = ? ";
						sql = "SELECT PRONO_LAST FROM transporter WHERE tran_code = ? ";
						pstmt = conn.prepareStatement(sql);
						pstmt.setString(1, tranCode);
						rs = pstmt.executeQuery();
						if( rs.next() )
						{
							tranProNo = rs.getString(1);
						}
						rs.close();
						rs = null;
						pstmt.close();
						pstmt = null;
						
						//Changed by sumit on 05/10/12 added condition where ref_ser = S-DSP
						//sql = "SELECT REF_ID FROM SHIP_DOCS WHERE SHIPMENT_ID = ?";
						sql = "SELECT REF_ID, REF_SER FROM SHIP_DOCS WHERE SHIPMENT_ID = ? AND DESP_CONFIRMED = 'N'";
						pstmt = conn.prepareStatement(sql);
						pstmt.setString(1, tranId);						
						rs = pstmt.executeQuery();
						while( rs.next() )
						{
							refId = rs.getString(1);
							//Changed by sumit on 05/10/12 getting value of refser
							refSerNew = checkNull(rs.getString("REF_SER"));
							
							System.out.println("ref_id " +refId+" refSer: ["+refSerNew.trim()+"]");
							//Changed by sumit on 05/10/12 add condition do not call despatch confirmed other than despatch
							//if(refId != null && refId.trim().length() > 0 )
							if(refId != null && refId.trim().length() > 0 && "S-DSP".equalsIgnoreCase(refSerNew.trim()))
							{
								
								System.out.println("after commit in ShipmentConf for id ["+ refId +"]");
								errString = confirmShipment("despatch", refId.trim(), xtraParam, forcedFlag, conn);
								
								//Changed by sumit on 05/10/12 updating ship_docs  start.
								System.out.println(" errString ---------------- > ["+errString);		
								
								//Changed by sumit on 05/10/12 updating desp_confirmed in ship docs table
								/*if ( newErro == null || newErro.trim().length() == 0)
								{*/
									updateShipDocs(refId, findError(errString));
								//}
								
								//errList.add(errString);
								// check digit to be removed from pro_no before update
								//if(proNo.length() > tranProNo.length())
								if((tranProNo != null && proNo != null) && proNo.length() > tranProNo.length())
								{
									proNo = proNo.substring(0,tranProNo.length());
								}
								sql = "UPDATE DESPATCH SET LORRY_NO = ?, SHIPMENT_ID = ?, TRAN_CODE = ?, LR_NO  = ?, LR_DATE = ?, pro_no = ? WHERE DESP_ID = ?";
								pstmt1 = conn.prepareStatement(sql);
								pstmt1.setString(1, lorryNo);
								pstmt1.setString(2, tranId);
								pstmt1.setString(3, tranCode);
								pstmt1.setString(4, lrNo);
								pstmt1.setTimestamp(5, lrDate);
								pstmt1.setString(6, proNo);
								pstmt1.setString(7, refId);
								pstmt1.executeUpdate();
								pstmt1.close();
								pstmt1 = null;
								//conn.commit();
								
								sql = "UPDATE TRANSPORTER SET PRONO_LAST  = ? WHERE TRAN_CODE = ?";
								pstmt1 = conn.prepareStatement(sql);
								pstmt1.setString(1, proNo);
								pstmt1.setString(2, tranCode);
								pstmt1.executeUpdate();
								pstmt1.close();
								pstmt1 = null;
								//conn.commit();								
									
							}
						}
						rs.close();
						rs = null;
						pstmt.close();
						pstmt = null;
						//Changed by sumit on 05/10/12 adding condition to check whether all despatch are confirmed or not 
						if( isCountSame(tranId, conn) || !("S-DSP".equalsIgnoreCase(refSer.trim())))
						{
							sql = "UPDATE SHIPMENT SET CONFIRMED = ? , CONF_DATE = ? WHERE SHIPMENT_ID = ?";
							pstmt = conn.prepareStatement(sql);
							pstmt.setString(1, "Y");
							pstmt.setDate(2, new java.sql.Date(new java.util.Date().getTime()));
							pstmt.setString(3, tranId);
							pstmt.executeUpdate();
							pstmt.close();
							pstmt = null;
							conn.commit();
							//Changed by sumit on 28/09/12 commented and written above.
							//ITMDBAccessLocal itmDBAccessLocal = new ITMDBAccessEJB();
							errString = itmDBAccessLocal.getErrorString("","VTCONFIRM","");
						}
					}
				}
			}
		}
		catch(Exception e)
		{
			try{
				conn.rollback();
			}
			catch(SQLException es)
			{
				System.out.println("Rollback exception : " + es.getMessage() + ":");
			}
			System.out.println("Exception : Shipment Confirm():" + e.getMessage() + ":");
			throw new ITMException(e);
		}
		finally
		{
			System.out.println("!! Closing Connection in Shipment Confirm() !!");
			try
			{
				conn.close();
				conn = null;
			}
			catch(Exception se){
				System.out.println(se.getMessage());
				throw new ITMException(se);
			}
		}
		return errString;
	}

	private String confirmShipment(String businessObj, String tranIdFr,String xtraParams, String forcedFlag , Connection conn) throws ITMException
	{
		String methodName = "gbf_post";
		String compName = "";
		String retString = "";
		String serviceCode = "";
		String serviceURI = "";
		String actionURI = "";
		String sql = "";
		//Connection conn = null;
		PreparedStatement pStmt = null;
		ResultSet rs = null;
		System.out.println("confirmShipment");
		try
		{
			//ConnDriver connDriver = new ConnDriver();
			//conn = connDriver.getConnectDB("DriverITM");

			//methodName = "";
			actionURI = "http://NvoServiceurl.org/" + methodName;
                           System.out.println(businessObj+"---"+tranIdFr+"---"+xtraParams+"---"+forcedFlag);

			sql = "SELECT SERVICE_CODE,COMP_NAME FROM SYSTEM_EVENTS WHERE OBJ_NAME = ? AND EVENT_CODE = 'pre_confirm' ";
			pStmt = conn.prepareStatement(sql);
			pStmt.setString(1,businessObj);
			rs = pStmt.executeQuery();
			if ( rs.next() )
			{
				serviceCode = rs.getString("SERVICE_CODE");
				compName = rs.getString("COMP_NAME");
			}
			System.out.println("serviceCode = "+serviceCode+" compName "+compName);
			sql = "SELECT SERVICE_URI,METHOD_NAME FROM SYSTEM_EVENT_SERVICES WHERE SERVICE_CODE = ? ";
			pStmt = conn.prepareStatement(sql);
			pStmt.setString(1,serviceCode);
			rs = pStmt.executeQuery();
			if ( rs.next() )//serviceURI = http://192.168.0.124/BaseE12DotNetService6-3-0-003/E12BusinessLogic6-3-0-003.asmx compName = nvo_business_object_dist_despatch   
			{
				serviceURI = rs.getString("SERVICE_URI");
                                methodName=rs.getString("METHOD_NAME");
			}
			System.out.println("serviceURI = "+serviceURI+" compName = "+compName);
			Service service = new Service();
			Call call = (Call)service.createCall();
			call.setTargetEndpointAddress(new java.net.URL(serviceURI));
			call.setOperationName( new javax.xml.namespace.QName("http://NvoServiceurl.org", methodName ) );
			call.setUseSOAPAction(true);
			call.setSOAPActionURI(actionURI);
			Object[] aobj = new Object[4];

			call.addParameter( new javax.xml.namespace.QName("http://NvoServiceurl.org", "component_name"), XMLType.XSD_STRING, ParameterMode.IN);
			call.addParameter( new javax.xml.namespace.QName("http://NvoServiceurl.org", "tran_id"), XMLType.XSD_STRING, ParameterMode.IN);
			call.addParameter( new javax.xml.namespace.QName("http://NvoServiceurl.org", "xtra_params"), XMLType.XSD_STRING, ParameterMode.IN);
			call.addParameter( new javax.xml.namespace.QName("http://NvoServiceurl.org", "forced_flag"), XMLType.XSD_STRING, ParameterMode.IN);

			aobj[0] = new String(compName.trim());
			aobj[1] = new String(tranIdFr.trim());
			aobj[2] = new String(xtraParams);
			aobj[3] = new String(forcedFlag);

			call.setReturnType(XMLType.XSD_STRING);

			retString = (String)call.invoke(aobj);

			System.out.println("Return string from NVO is:==>["+retString+"]");

		}
		catch(Exception e)
		{
			e.printStackTrace();
			throw new ITMException(e);
		}
		finally
		{
			try
			{
				if (pStmt != null )
				{
					pStmt.close();
					pStmt = null;
				}
				 /*if( conn != null ){
					conn.close();
					conn = null;
				}*/
			}
			catch(Exception e)
			{
                            System.out.println("Exception inCalling confirmed");
                            e.printStackTrace();
                            try{
                            conn.rollback();

                            }catch (Exception s)
                            {
                                System.out.println("Unable to rollback");
                                s.printStackTrace();
                            }
            				throw new ITMException(e);
                        }
		}
		return retString;
	}
	//Changed by sumit on 02/12/12 for checking null start.
	private String checkNull( String input )	
	{
		if ( input == null )
		{
			input = "";
		}
		return input;
	}
	//Changed by sumit on 02/12/12 for checking null end.
	
	//Changed by sumit on 05/10/12 retrieving error string start.
	private HashMap findError(String errorString) throws ITMException
	{
		Document errorDom = null;
		NodeList parentNodeList = null;
		NodeList childList = null;
		int parentNodeListLength ;
		String description = "";
		Element elementAttr = null;
		Map error =  new HashMap();
		String columnValue ="",nodeName= "",errType = "";
		try
		{
			if(errorString != null && errorString.trim().length()!=0)
			{
				errorDom = genericUtility.parseString(errorString); 
			}
			
			parentNodeList = errorDom.getElementsByTagName("error");
			parentNodeListLength = parentNodeList.getLength();	
			
			for(int row = 0; row < parentNodeListLength; row++)
			{
				Node childNode = parentNodeList.item(row);
				nodeName = childNode.getNodeName();
				//elementAttr = (Element)parentNode;
				errType = childNode.getAttributes().getNamedItem("type").getNodeValue();
				System.out.println(" error type ->["+errType+"]");
				if( "E".equalsIgnoreCase(errType))
				{
					description = checkNull(GenericUtility.getInstance().getColumnValueFromNode("description", errorDom.getElementsByTagName("error").item(row)));
				}				
			}	
			description = description.replace("\"", " ");
			description = description.replace("'", "");
			error.put("type", errType);
			error.put("description", description);
			System.out.println(" error description - > ["+error+"]");				
		}
		catch (Exception e)
		{
			throw new ITMException(e);
		}
		return (HashMap) error;
	}
	//Changed by sumit on 05/10/12 retrieving error string end.
	//Changed by sumit on 05/10/12 counting ship detail start.
	private boolean isCountSame(String shipId, Connection conn) throws ITMException
	{
		String sql = "";
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		int count = 0, count1 = 0;
		boolean isSame = false;
		try
		{
			
			sql = " SELECT COUNT(*) AS COUNT FROM SHIP_DOCS WHERE SHIPMENT_ID = ? ";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, shipId);
			rs = pstmt.executeQuery();
			if( rs.next())
			{
				count = rs.getInt("COUNT");
			}
			rs.close();rs = null;			
			pstmt.close();pstmt = null;	
			
			sql = " SELECT COUNT(*) AS COUNT FROM SHIP_DOCS WHERE SHIPMENT_ID = ? AND DESP_CONFIRMED = ? ";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, shipId);
			pstmt.setString(2, "Y");		
			rs = pstmt.executeQuery();
			if( rs.next())
			{
				count1 = rs.getInt("COUNT");
			}
			rs.close();rs = null;			
			pstmt.close();pstmt = null;	
			if (count == count1)
			{
				isSame = true;
			}
			else
			{
				isSame = false;
			}
			System.out.println(" isSame ->["+isSame+"]");
		}		
		catch (Exception e)
		{
			throw new ITMException(e);
		}
		finally
		{
			try {
				
				if (rs != null) 
				{
					rs.close();
					rs = null;
				}
				if (pstmt != null) 
				{
					pstmt.close();
					pstmt = null;
				}
			} catch (Exception e2) 
			{
				throw new ITMException(e2);
			}
		}
		return isSame;
	}
	//Changed by sumit on 05/10/12 counting ship detail end.
	//Changed by sumit on 05/10/12 update desp_confirmed in ship_docs ship detail start.
	private String updateShipDocs ( String refId, HashMap error) throws ITMException
	{
		String sql = "";
		PreparedStatement pstmt1 = null;
		Connection conn = null;
		ConnDriver connDriver = null;
		try
		{
			connDriver = new ConnDriver();
			conn = connDriver.getConnectDB("DriverITM");
			connDriver = null;
			sql = " UPDATE SHIP_DOCS SET DESP_CONFIRMED = ?, ERROR_MSG = ? WHERE REF_ID = ? ";
			pstmt1 = conn.prepareStatement(sql);
			 if( "E".equals(error.get("type").toString()))
			 {
				pstmt1.setString(1, "N");
				pstmt1.setString(2, error.get("description").toString());
				pstmt1.setString(3, refId);
			 }
			 else
			 {
				pstmt1.setString(1, "Y");
				pstmt1.setString(2, "");
				pstmt1.setString(3, refId);
			 }
			pstmt1.executeUpdate();
			pstmt1.close();
			pstmt1 = null;
			conn.commit();
		}
		catch( Exception e)
		{
			try
			{
                conn.rollback();                
			}
			catch (Exception s)
            {
                System.out.println("Unable to rollback");
                s.printStackTrace();
            }
			throw new ITMException(e);
		}
		finally
		{
			try 
			{
				if ( pstmt1 != null)
				{
					pstmt1.close();
					pstmt1 = null;
				}
				if( conn != null)
				{
					conn.close();
					conn = null;
				}
			} catch (Exception e2) 
			{
				throw new ITMException(e2);
			}
		}
		
		return null;
	}
	//Changed by sumit on 05/10/12 update desp_confirmed in ship_docs ship detail end.
}
