package com.fitbank.web;

import java.sql.Date;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;

import com.fitbank.common.ApplicationDates;
import com.fitbank.common.Clonador;
import com.fitbank.common.Uid;
import com.fitbank.common.crypto.Decrypt;
import com.fitbank.common.exception.FitbankException;
import com.fitbank.common.helper.FormatDates;
import com.fitbank.common.logger.FitbankLogger;
import com.fitbank.dto.GeneralResponse;
import com.fitbank.dto.management.Criterion;
import com.fitbank.dto.management.Detail;
import com.fitbank.dto.management.Field;
import com.fitbank.dto.management.Record;
import com.fitbank.dto.management.Table;

public class DataManage extends HashMap<Object, Object> {

	private static final long serialVersionUID = 1L;

	public static final String TRN_DATA = "__trnData";

	public static final String KEY = "dm";

	public static final String DETAIL_KEY = "det";

	public static final String PREPARED_CTL = "__prep__";

	public static final String PAGING_TABLE_CTL = "_paging_";

	public static final String PARAM_CAPTURE = "__capture";

	public static final String PARAM_CAPTURE_NAME = "__capture_name";

	public List<String> messages = new ArrayList<String>();

	public ServletRequest request;

	private HttpSession httpSession;

	public DataManage() {
		super();

	}

	public DataManage(ServletRequest request) {
		super();
		this.request = request;
	}

	public String finantial() {
		FacesUtil util = new FacesUtil(this, this.request);
		try {
			Detail det = this.getDetail();
			det.setType(MessageTypes.MAN.name());
			Decrypt de = new Decrypt();
			if (!de.isWebencrypt()) {
				String pin = (String) det.findFieldByNameCreate("PIN").getValue();
				det.findFieldByNameCreate("PIN").setValue(de.encrypt(pin));
			}
			this.process(det, null);
			return this.go();
		} catch (Exception e) {
			e.printStackTrace();
			util.addErrorMessage(e);
			return "";
		}
	}

	public void formatMessages() throws Exception {
		if (this.getMessages().size() == 1) {
			this.put("errorMessage", this.getMessages().get(0));
		} else {
			String format = "";
			for (String s : this.getMessages()) {
				format += s + " \n";
			}
			this.put("errorMessage", format);
		}
		this.getMessages().clear();
	}

	@Override
	public Object get(Object key) {
		FacesUtil util = new FacesUtil();
		util.setDm(this);
		util.setRequest(this.request);
		Object sessionId = super.get("sessionId");
		if (((String) key).compareTo("requestDataOnly") == 0) {
			return this.getRequestDataOnly();
		}
		if (((String) key).compareTo("requestDataForce") == 0) {
			return this.getRequestDataForce();
		}
		if (((String) key).compareTo("requestData") == 0) {
			try {
				return this.getRequestData();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (((String) key).compareTo("removeLoginMessage") == 0) {
			this.getRemoveLoginMessage();
			return "";
		}

		if (((String) key).compareTo("prepareData") == 0) {
			try {
				return this.getPrepareData();
			} catch (Exception e) {
				return e.getMessage();
			}
		}
		if (((String) key).compareTo("logout") == 0) {
			if (sessionId == null) {
				return "";
			}
			try {
				if (util.getSession().getAttribute("sessionId") != null) {
					return this.logout();
				} else {
					return "";
				}
			} catch (Exception e1) {
				return "";
			}
		}
		if (((String) key).compareTo("menu") == 0) {
			// System.out.println("Prepara el menú");
			if (sessionId == null) {
				return "";
			}
			MenuLoader ml = new MenuLoader(this, util.getRequest(), util.getSession());
			try {
				Detail det = ml.query();
				util.getSession().setAttribute("_menu", det);
			} catch (Exception e) {
				util.addErrorMessage(e);
			}
			return "";
		}
		if (((String) key).compareTo("submenu") == 0) {
			// System.out.println("Prepara el sub-menú");
			util.getSession().setAttribute("_submenu", "");
			if (sessionId == null) {
				return "";
			}
			MenuLoader ml = new MenuLoader(this, this.request, util.getSession());
			try {
				util.getSession().setAttribute("_submenu", ml.getSubMenu());
			} catch (Exception e) {
				e.printStackTrace();
				util.addErrorMessage(e);
			}
			return "";
		}
		if (((String) key).compareTo("go") == 0) {
			return this.go();
		}
		if (((String) key).compareTo("next") == 0) {
			return this.next();
		}
		if (((String) key).compareTo("prev") == 0) {
			return this.prev();
		}
		if (((String) key).compareTo("query") == 0) {
			return this.query();
		}
		if (((String) key).compareTo("save") == 0) {
			return this.save();
		}
		if (((String) key).compareTo("finantial") == 0) {
			return this.finantial();
		}
		if (((String) key).compareTo("formatMessages") == 0) {
			try {
				this.formatMessages();
				return "";
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		Object obj = super.get(key);
		return obj;
	}

	private Detail getDetail() throws Exception {
		return this.getDetail(null);
	}

	private Detail getDetail(String pKey) throws Exception {
		FacesUtil util = new FacesUtil();
		util.setDm(this);
		util.setRequest(this.request);
		String key = this.getDetailKey(pKey);
		Detail det = (Detail) this.get(key);
		if (det == null) {
			det = new Detail();
			Transaction trn = util.getTransactionMetaData();
			if (trn != null) {
				this.prepareDetail(det, trn);
				this.put(key, det);
			}
		} else {
			det.findFieldByNameCreate(PREPARED_CTL).setValue("true");

		}
		return det;
	}

	public String getDetailKey(String pKey) {
		try {
			FacesUtil util = new FacesUtil();
			util.setDm(this);
			util.setRequest(this.request);
			String key = pKey;
			if (key == null) {
				key = DataManage.DETAIL_KEY;
				String paramKey = util.getParameterString("_detail_");

				if ((paramKey != null) && (paramKey.compareTo("") != 0)) {
					key = paramKey;
				} else {
					paramKey = (String) util.getSession().getAttribute("_detail_");
					// this.getSession().setAttribute("_detail_","");
					if ((paramKey != null) && (paramKey.compareTo("") != 0)) {
						key = paramKey;
					}
				}

			}
			return key;
		} catch (Exception e) {
			return DETAIL_KEY;
		}
	}

	public HttpSession getHttpSession() {
		return this.httpSession;
	}

	public List<String> getMessages() {
		return this.messages;
	}

	public String getPrepareData() throws Exception {
		FacesUtil util = new FacesUtil();
		util.setDm(this);
		util.setRequest(this.request);
		String init = util.getParameterString("_init_");
		if (init != null) {
			this.removeOldData();
		}
		Detail det1 = this.getDetail();
		if (det1 != null) {
			return "";
		}

		String key = DataManage.DETAIL_KEY;
		String trnKey = DataManage.TRN_DATA;
		String paramKey = this.getDetailKey(null);
		if (key.compareTo(paramKey) != 0) {
			key = paramKey;
			trnKey = paramKey;
		}
		Transaction trn = (Transaction) util.getSession().getAttribute(trnKey);
		Detail det = new Detail();
		this.prepareDetail(det, trn);
		this.put(key, det);
		return "";
	}

	public void getRemoveLoginMessage() {
		super.put("loginMessage", "");
	}

	public String getRequestData() {
		FacesUtil util = new FacesUtil(this, this.request);
		String init = util.getParameterString("_init_");
		String exp = util.getParameterString("_exp");

		if (exp != null) {
			return "";
		}
		if (init != null) {
			if (init.compareTo("1") == 0) {
				this.removeOldData();
			} else {
				return "";
			}
		} else {
			return "";
		}

		try {
			if (((String) this.getDetail().findFieldByNameCreate("LAST_OPERATION").getValue()).compareTo(MessageTypes.MAN.name()) == 0) {
				Detail det = this.getDetail();
				det.findFieldByNameCreate("LAST_OPERATION").setValue("");
				return "";
			}
		} catch (Exception e) {
			;
		}
		return this.query();
	}

	public String getRequestDataForce() {
		this.removeOldData();
		return this.query();
	}

	public String getRequestDataOnly() {
		try {
			Detail det = this.getDetail();
			String prepared_ctl = (String) det.findFieldByNameCreate(PREPARED_CTL).getValue();
			if ((prepared_ctl != null) && (prepared_ctl.compareTo("true") == 0)) {
				return "";
			}
			return this.query();
		} catch (Exception ex) {
			ex.printStackTrace();
			return "error.jsp";
		}

	}

	public String go() {
		FacesUtil util = new FacesUtil(this, this.request);
		try {
			String page = util.getParameterString("_page");
			FitbankLogger.getLogger().debug("P�gina " + page);
			String det = util.getParameterString("_det_capture");
			String detail = util.getParameterString("_detail_");
			if ((detail != null) && (detail.compareTo("") != 0)) {
				util.getSession().setAttribute("_detail_", detail);
			}
			Detail oDetail = this.getDetail(det);
			util.capture(oDetail);
			if (page == null) {
				return "";
			}
			String name = page.replaceAll("\\.", "").replaceAll("\\/", "");
			// util.createNavigationRule(name, page);
			FitbankLogger.getLogger().debug(">>" + name);
			if ((oDetail != null) && (oDetail.getResponse() != null)) {
				util.addMessage(oDetail.getResponse().getUserMessage());
			}
			return name;
		} catch (Throwable e) {
			util.addErrorMessage(e);
		}
		return "";
	}

	public String login() {
		FacesUtil util = new FacesUtil(this, this.request);
		try {
			Detail det = this.getDetail();
			det.findFieldByNameCreate(PREPARED_CTL).setValue("true");
			det.setSubsystem("01");
			det.setTransaction("0000");
			det.setVersion("01");
			/*
			 * Field send_str = new Field("SIAF_LOGIN"); det.addField(send_str); Field
			 * receive_str = new Field("SIAF_LOGINHB_SAL"); det.addField(receive_str);
			 */
			det.setCompany(2);
			// det.findFieldByNameCreate("RUC").setValue(this.get("ruc"));
			det.setUser((String) this.get("user"));
			det.setAccountingdate(new Date(System.currentTimeMillis()));
			// util.getSession().setAttribute("TARJETA", det.getUser());
			// Field send = new Field("SEND_STR", "SIAF_LOGIN");
			// det.addField(send);
			// Field receive = new Field("RECEIVE_STR", "SIAF_LOGINHB_SAL");
			// det.addField(receive);
			Decrypt de = new Decrypt();
			if (!de.isWebencrypt()) {
				det.setPassword(de.encrypt((String) this.get("password")));
			}
			det.setIpaddress(util.getRequest().getRemoteAddr());
			det.setType(MessageTypes.SIG.name());
			String message = Uid.getString();
			int tamanio = message.length();
			if (tamanio < 30){
				message = det.getUser().substring(0, (30-tamanio-1)) + message;			
			}
			det.setMessageid(message);
			det.setChannel("PC");
			this.remove("sessionId");
			det.setSessionid("LOGIN");
			BussinessDelegate bd = new BussinessDelegate();
			this.clear();
			det = bd.process(det);
			GeneralResponse resp = det.getResponse();
			if (resp.getCode().compareTo(GeneralResponse.OK) != 0) {
				if (resp.getCode().compareTo("000001") == 0) {
					super.put("loginMessage", "");
					super.put("user", det.getUser());
					super.put("password", det.getPassword());
					super.put("sessionId", det.getSessionid());
					super.put("language", det.getLanguage());
					util.getSession().setAttribute("i18n", det.getLanguage().toLowerCase());
					Locale locale = new Locale(det.getLanguage().toLowerCase());
					ResourceBundle res = ResourceBundle.getBundle("i18n", locale);
					ResourceFit resourceFit = new ResourceFit(res);
					util.getSession().setAttribute("lan", resourceFit);
					super.put("terminal", det.getTerminal());
					return "changePassword.jsp";
				}
				super.put("loginMessage", resp.getUserMessage());
				return "login.jsp";
			} else {
				super.put("loginMessage", "");
				super.put("user", det.getUser());
				super.put("password", det.getPassword());
				super.put("sessionId", det.getSessionid());
				super.put("language", det.getLanguage());
				util.getSession().setAttribute("i18n", det.getLanguage().toLowerCase());
				Locale locale = new Locale(det.getLanguage().toLowerCase());
				ResourceBundle res = ResourceBundle.getBundle("i18n", locale);
				ResourceFit resourceFit = new ResourceFit(res);
				util.getSession().setAttribute("lan", resourceFit);
				super.put("terminal", det.getTerminal());
				super.put("channel", "PC");
				super.put("profile", det.getRole());
				super.put("company", det.getCompany());
				super.put("originBranch", det.getOriginbranch());
				super.put("originOffice", det.getOriginoffice());
				super.put("securityLevel", det.getSecuritylevel());
				super.put("accountingDate", det.getAccountingdate());
				super.put("area", det.getArea());
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				super.put("date", sdf.format(new java.util.Date()));
				super.put("time", new java.util.Date());
				super.put("branchName", det.findFieldByNameCreate("_BranchName").getValue());
				super.put("officeName", det.findFieldByNameCreate("_OfficeName").getValue());
				super.put("areaName", det.findFieldByNameCreate("_AreaName").getValue());
				super.put("roleName", det.findFieldByNameCreate("_RoleName").getValue());
				util.getSession().setAttribute("CPERSONA", det.findFieldByNameCreate("CPERSONA").getValue());
			}
			return "access.jsp";
		} catch (Exception e) {
			util.addErrorMessage(e);
			return "login.jsp";
		}
	}

	@SuppressWarnings("unchecked")
	public String logout() {
		FacesUtil util = new FacesUtil(this, this.request);
		try {
			Detail logoutDet = new Detail();
			this.prepareHeaderData(logoutDet, util.getRequest());
			logoutDet.setSubsystem("01");
			logoutDet.setTransaction("9999");
			logoutDet.setVersion("01");
			logoutDet.findFieldByNameCreate(PREPARED_CTL).setValue("true");
			Table tab = new Table("TUSUARIOSESIONES", "TUSUARIOSESIONES");
			Record rec = new Record();
			tab.addRecord(rec);
			rec.findFieldByNameCreate("CUSUARIO").setValue(logoutDet.getUser());
			rec.findFieldByNameCreate("FHASTA").setValue(FormatDates.getDefaultExpiryTimestamp());
			rec.findFieldByNameCreate("SESION").setValue(logoutDet.getSessionid());
			rec.findFieldByNameCreate("VERSIONCONTROL").setValue("-1");
			logoutDet.addTable(tab);
			logoutDet.setType(MessageTypes.MAN.name());
			logoutDet = this.process(logoutDet, this.request);
			if (logoutDet.getResponse().getCode().compareTo(GeneralResponse.OK) == 0) {
				this.clear();
				// util.getSession().invalidate();
				HttpSession session = util.getSession();
				Enumeration<String> e = session.getAttributeNames();
				List<String> n = new ArrayList<String>();
				while (e.hasMoreElements()) {
					n.add(e.nextElement());
				}
				for (int i = 0; i < n.size(); i++) {
					session.removeAttribute(n.get(i));
				}
			}
			return "";
		} catch (Exception e) {
			util.addErrorMessage(e);
			return "";
		}
	}

	private void manageFinanResponse(Detail pDetail, Detail det) {
		// Detail det=(Detail)this.get("det");
		if (det == null) {
			return;
		}
		Table fin = det.findTableByAlias("FINANCIERO");
		Table fin1 = pDetail.findTableByAlias("FINANCIERO");
		if ((fin != null) && (fin1 != null)) {
			/*
			 * for (Record rec : fin.getRecords()) { String
			 * cod=""+rec.findFieldByNameCreate("CODIGO").getValue(); for (Record rec1
			 * : fin1.getRecords()) { String
			 * cod1=""+rec1.findFieldByNameCreate("CODIGO").getValue();
			 * if(cod.compareTo(cod1)==0){
			 * rec.findFieldByNameCreate("VALOR").setValue(
			 * rec1.findFieldByNameCreate("VALOR").getValue()); break; } } }
			 */
			det.removeTable("FINANCIERO");
			det.addTable(fin1);
		}
		for (Field f : det.getFields()) {
			Field f1 = pDetail.findFieldByName(f.getName());
			if (f1 != null) {
				f.setValue(f1.getValue());
			}
		}
		super.put(DETAIL_KEY, det);
	}

	public String newRecord() {
		FacesUtil util = new FacesUtil(this, this.request);
		try {
			String tableAlias = (String) util.getParameterString("_table");
			if (tableAlias == null) {
				throw new Exception("Tabla no definida");
			}
			Detail oDetail = this.getDetail();
			Table table = oDetail.findTableByAlias(tableAlias);
			if (table == null) {
				throw new Exception("Tabla " + tableAlias + " no encontrada");
			}
			Record rec = (Record) table.get("_record0");
			if (rec == null) {
				throw new Exception("Tabla " + tableAlias + " tiene estructura de Registro");
			}
			rec = Clonador.clonar(rec);
			List<Field> fields = rec.getFields();
			for (Field field : fields) {
				field.setValue("");
				field.setOldValue("");
				field.setRealValue("");
			}
			table.addRecord(rec);
		} catch (Throwable e) {
			util.addErrorMessage(e);
		}
		return "";
	}

	public String next() {
		return this.next(this.request);
	}

	public String next(ServletRequest pReq) {
		FacesUtil util = new FacesUtil(this, pReq);
		try {
			Detail det = this.getDetail();
			String pagingTables = (String) det.findFieldByNameCreate(PAGING_TABLE_CTL).getValue();
			if ((pagingTables != null) && (pagingTables.compareTo("") == 0)) {
				pagingTables = null;
			}
			for (Table table : det.getTables()) {
				if (pagingTables != null) {
					if (pagingTables.indexOf(table.getAlias()) < 0) {
						continue;
					}
				}
				if (table.isFinancial() || (table.getAlias().compareTo("__origin") == 0) || (table.getAlias().compareTo("EXCHANGE") == 0)) {
					continue;
				}
				String has = table.getHasMorePages();
				if ((has == null) || (has.compareTo("0") != 0)) {
					table.setPageNumber(table.getPageNumber() + 1);
				} else {
					throw new Exception("Se encuentra en la Ultima Página ");
				}
			}
			return this.query();
		} catch (Exception e) {
			util.addErrorMessage(e);
			return "";
		}
	}

	public String password() {
		FacesUtil util = new FacesUtil(this, this.request);
		try {
			Detail det = this.getDetail();
			det.findFieldByNameCreate(PREPARED_CTL).setValue("true");
			det.setSubsystem("01");
			det.setTransaction("0201");
			det.setVersion("01");
			/*
			 * Field send_str = new Field("SIAF_LOGIN"); det.addField(send_str); Field
			 * receive_str = new Field("SIAF_LOGINHB_SAL"); det.addField(receive_str);
			 */
			det.setCompany(2);
			// det.findFieldByNameCreate("RUC").setValue(this.get("ruc"));
			det.setUser((String) this.get("user"));
			det.setAccountingdate(new Date(System.currentTimeMillis()));
			// util.getSession().setAttribute("TARJETA", det.getUser());
			// Field send = new Field("SEND_STR", "SIAF_LOGIN");
			// det.addField(send);
			// Field receive = new Field("RECEIVE_STR", "SIAF_LOGINHB_SAL");
			// det.addField(receive);

			det.setIpaddress(util.getRequest().getRemoteAddr());
			det.setType(MessageTypes.MAN.name());
			det.setMessageid(Uid.getString());
			det.setChannel("PC");
			this.remove("sessionId");
			det.setSessionid("LOGIN");
			det.setType(MessageTypes.MAN.name());
			Decrypt de = new Decrypt();
			if (!de.isWebencrypt()) {
				String pwdAnterior = (String) det.findFieldByNameCreate("PWDANTERIOR").getValue();
				String pwdNuevo = (String) det.findFieldByNameCreate("PWDNUEVO").getValue();
				String pwdConfirmar = (String) det.findFieldByNameCreate("PWDCONFIRMAR").getValue();
				det.findFieldByNameCreate("PWDANTERIOR").setValue(de.encrypt(pwdAnterior));
				det.findFieldByNameCreate("PWDNUEVO").setValue(de.encrypt(pwdNuevo));
				det.findFieldByNameCreate("PWDCONFIRMAR").setValue(de.encrypt(pwdConfirmar));
				det.findFieldByNameCreate("USUARIO").setValue(det.getUser());
			}
			det.findFieldByNameCreate("_AUTOLOTE").setValue("1");
			BussinessDelegate bd = new BussinessDelegate();
			det = bd.process(det);
			GeneralResponse resp = det.getResponse();

			if (resp.getCode().compareTo(GeneralResponse.OK) != 0) {
				super.put("loginMessage", resp.getUserMessage());
				return "password.jsp";

			} else {

				super.put("loginMessage", "PASSWORD CAMBIADO SATISFACTORIAMENTE");
				return "login.jsp";

			}

		} catch (Exception e) {
			e.printStackTrace();
			super.put("loginMessage", e.getMessage());
			return "password.jsp";
		}
	}

	public void prepareDetail(Detail pDetail, Transaction pTrn) throws Exception {
		FacesUtil util = new FacesUtil();
		util.setDm(this);
		util.setRequest(this.request);
		pDetail.setSubsystem(pTrn.getSubsystem());
		pDetail.setTransaction(pTrn.getTransaction());
		pDetail.setVersion(pTrn.getVersion());
		this.prepareHeaderData(pDetail, util.getRequest());
		Iterator<Table> it = pTrn.getTables().iterator();
		while (it.hasNext()) {
			Table table = it.next();
			pDetail.addTable(table);
			Iterator<Record> it1 = table.getRecords().iterator();
			if (it1.hasNext()) {
				this.put("_tempRec_" + table.getAlias(), it1.next());
			}
		}
		Iterator<Field> itctl = pTrn.getControlFields().iterator();
		while (itctl.hasNext()) {
			pDetail.addField(itctl.next());
		}
	}

	public void prepareHeaderData(Detail pDetail, ServletRequest pRequest) throws Exception {
		pDetail.setUser((String) this.get("user"));
		Decrypt de = new Decrypt();
		if (!de.isWebencrypt()) {
			pDetail.setPassword(de.encrypt((String) this.get("password")));
		}
		try {
			pDetail.setIpaddress(pRequest.getRemoteAddr());
		} catch (Exception e) {
			FitbankLogger.getLogger().warn("Al obtener el IP: " + e.getMessage());
		}
		pDetail.setSessionid((String) this.get("sessionId"));
		pDetail.setLanguage((String) this.get("language"));
		pDetail.setTerminal((String) this.get("terminal"));
		pDetail.setChannel((String) this.get("channel"));
		pDetail.setRole((Integer) this.get("profile"));
		pDetail.setCompany((Integer) this.get("company"));
		pDetail.setOriginbranch((Integer) this.get("originBranch"));
		pDetail.setOriginoffice((Integer) this.get("originOffice"));
		pDetail.setSecuritylevel((Integer) this.get("securityLevel"));
		if (this.get("accountingDate") == null) {
			pDetail.setAccountingdate(new Date(System.currentTimeMillis()));
		} else {
			pDetail.setAccountingdate((Date) this.get("accountingDate"));
		}
		pDetail.setArea((String) this.get("area"));
	}

	public String prev() {
		return this.prev(this.request);
	}

	public String prev(ServletRequest pReq) {
		FacesUtil util = new FacesUtil(this, pReq);
		try {
			Detail det = this.getDetail();
			String pagingTables = (String) det.findFieldByNameCreate(PAGING_TABLE_CTL).getValue();
			if ((pagingTables != null) && (pagingTables.compareTo("") == 0)) {
				pagingTables = null;
			}
			for (Table table : det.getTables()) {
				if (table.isFinancial() || (table.getAlias().compareTo("__origin") == 0) || (table.getAlias().compareTo("EXCHANGE") == 0)) {
					continue;
				}
				if (pagingTables != null) {
					if (pagingTables.indexOf(table.getAlias()) < 0) {
						continue;
					}
				}
				int page = table.getPageNumber();
				if (page > 1) {
					table.setPageNumber(table.getPageNumber() - 1);
				} else {
					throw new Exception("Se encuentra en la primera PÃ¡gina");
				}
			}
			return this.query();
		} catch (Exception e) {
			util.addErrorMessage(e);
			return "";
		}
	}

	private Detail process(Detail pDetail, ServletRequest pRequest) throws Exception {
		FacesUtil util = new FacesUtil();
		util.setRequest(pRequest);
		util.setDm(this);
		Transaction trn = util.getTransactionMetaData();
		String val = (String) pDetail.findFieldByNameCreate(PREPARED_CTL).getValue();
		if ((val == null) || (val.compareTo("true") != 0)) {
			this.prepareDetail(pDetail, trn);
		}
		String realMSG = util.getSessionString("_REAL_MSG");
		if (realMSG != null) {
			pDetail.setMessageid(realMSG);
			util.getSession().removeAttribute("_REAL_MSG");
		} else {
			pDetail.setMessageid(Uid.getString());
		}
		BussinessDelegate bd = new BussinessDelegate();
		String key = this.getDetailKey(null);
		boolean __origin = false;
		if (pDetail.getType().compareTo("CON") == 0) {
			Table ori = pDetail.findTableByAlias("__origin");
			if (ori != null) {
				ori.setReadonly(true);
				__origin = true;
			}
		}
		pDetail = bd.process(pDetail);
		if (__origin) {
			Table ori = pDetail.findTableByAlias("__origin");
			if (ori != null) {
				ori.setReadonly(false);
			}
		}
		this.put("lastOperation", pDetail.getType());
		if (pDetail.getType().compareTo(MessageTypes.MAN.name()) == 0) {
			pDetail.findFieldByNameCreate("LAST_OPERATION").setValue("MAN");
		}
		this.validateResponse(pDetail.getResponse(), pRequest);
		this.put(key, pDetail);
		return pDetail;
	}

	public String query() {
		return this.query(this.request);
	}

	public String query(ServletRequest pRequest) {
		long ini = System.currentTimeMillis();
		FacesUtil util = new FacesUtil(this, pRequest);
		try {
			Detail det = this.getDetail();
			if ((det.getSubsystem().compareTo("03") == 0) && (det.getTransaction().compareTo("7002") == 0)) {
				Map<String, String> m = util.getSendingParams();
				for (String key : m.keySet()) {
					det.findFieldByNameCreate(key).setValue(m.get(key));
				}
				det.findFieldByNameCreate("_BranchName").setValue(super.get("branchName"));
				det.findFieldByNameCreate("_OfficeName").setValue(super.get("officeName"));
				det.findFieldByNameCreate("_AreaName").setValue(super.get("areaName"));
				det.findFieldByNameCreate("_RoleName").setValue(super.get("roleName"));
			}
			// det.findFieldByNameCreate(PREPARED_CTL).setValue("false");

			Detail qryDet = new Detail();
			this.prepareHeaderData(qryDet, util.getRequest());
			qryDet.setSubsystem(det.getSubsystem());
			qryDet.setTransaction(det.getTransaction());
			qryDet.setVersion(det.getVersion());
			for (Field ctl : det.getFields()) {
				qryDet.addField(ctl);
			}
			for (Table table : det.getTables()) {
				if (table.isReadonly()) {// || table.isFinancial()) {
					qryDet.addTable(table);
					continue;
				}
				Table tab = new Table(table.getName(), table.getAlias());
				tab.setStructure(table.getStructure());
				qryDet.addTable(tab);
				tab.setRequestedRecords(table.getRequestedRecords());
				tab.setPageNumber(table.getPageNumber());
				for (Criterion cri : table.getCriteria()) {
					tab.addCriterion(cri);
				}
				if (tab.getStructure() != null) {
					Record rec = new Record();
					tab.clearRecords();
					List<Field> fields = tab.getStructure().getFields();
					for (Field field : fields) {
						rec.findFieldByNameCreate(field.getName()).setRealValue(null);
					}
					tab.addRecord(rec);
				} else {
					Iterator<Record> rec = table.getRecords().iterator();
					if (rec.hasNext()) {
						Record record = rec.next();
						List<Field> fields = record.getFields();
						for (Field field : fields) {
							field.setRealValue(null);
						}
						tab.addRecord(record);
					} else {
						Record rec1 = (Record) this.get("_tempRec_" + table.getAlias());
						if (rec1 != null) {
							tab.addRecord(rec1);
						}
					}
				}
			}
			qryDet.setType(MessageTypes.CON.name());
			this.process(qryDet, pRequest);
			FitbankLogger.getLogger().info(
					"Tiempo de Consulta de la transaccion  " + qryDet.getSubsystem() + "/" + qryDet.getTransaction() + "/" + qryDet.getVersion() + " "
							+ FormatDates.getInstance().getTimeCountFormat().format(new Date(System.currentTimeMillis() - ini)));
			return "";
		} catch (Exception e) {
			util.addErrorMessage(e);
			return "";
		}
	}

	private void removeOldData() {
		FacesUtil util = new FacesUtil();
		util.setDm(this);
		util.setRequest(this.request);
		Set<Object> k = this.keySet();
		List<Object> keys = new ArrayList<Object>();
		for (Object key : k) {
			keys.add(key);
		}
		for (Object key : keys) {
			Object obj = this.get(key);
			if ((obj instanceof Detail) || (obj instanceof Record) || (obj instanceof Table)) {
				String sKey = "" + key;
				if (sKey.indexOf("det_") != 0) {
					this.remove(key);
				}
			}
		}
		String detailSet = (String) util.getSession().getAttribute("_detail_set_");
		if ((detailSet == null) || (detailSet.compareTo("1") != 0)) {
			util.getSession().setAttribute("_detail_", "");
		} else {
			util.getSession().setAttribute("_detail_set_", "");
		}
		this.put("param", new ParamMap(this));
		// this.clear();
	}

	public String save() {
		return this.save(this.request);
	}

	public String save(ServletRequest pReq) {
		FacesUtil util = new FacesUtil(this, pReq);
		try {
			Detail detail = this.getDetail();
			Detail det = Clonador.clonar(detail);
			det.setType(MessageTypes.MAN.name());
			String capture = util.getParameterString(PARAM_CAPTURE);
			if ((capture != null) && (capture.compareTo("1") == 0)) {
				String data = util.captureData();
				String captureName = util.getParameterString(PARAM_CAPTURE_NAME);

				Table tbl = det.findTableByAlias("mf");
				if (tbl == null) {
					tbl = new Table("TMOVIMIENTOSFRECUENTES", "mf");
				} else {
					tbl.clearRecords();
				}
				Record rec = new Record();
				tbl.addRecord(rec);
				rec.findFieldByNameCreate("CUSUARIO").setRealValue(det.getUser());
				rec.findFieldByNameCreate("NOMBRETRANSACCION").setRealValue(captureName);
				rec.findFieldByNameCreate("CSUBSISTEMA").setRealValue(det.getSubsystem());
				rec.findFieldByNameCreate("CTRANSACCION").setRealValue(det.getTransaction());
				rec.findFieldByNameCreate("VERSIONTRANSACCION").setRealValue(det.getVersion());
				rec.findFieldByNameCreate("FHASTA").setRealValue(ApplicationDates.getDefaultExpiryDate());
				rec.findFieldByNameCreate("FDESDE").setRealValue(new Timestamp(System.currentTimeMillis()));
				rec.findFieldByNameCreate("DATOS").setRealValue(data);
				det.addTable(tbl);
			}
			List<String> emptyTables = new ArrayList<String>();
			for (Table tbl : det.getTables()) {
				if (tbl.isFinancial() || tbl.isReadonly() || (tbl.getAlias().compareTo("EXCHANGE") == 0)) {
					continue;
				}
				tbl.clearUnchangedRecords();
				if (tbl.getRecordCount() == 0) {
					emptyTables.add(tbl.getAlias());
				}
			}
			for (String alias : emptyTables) {
				det.removeTable(alias);
			}
			Detail det1 = this.process(det, pReq);
			util.getSession().setAttribute("_responseCode", det1.getResponse().getCode());
			this.manageFinanResponse(det1, detail);
			String finan = (det1.hasFinancialRequest()) ? "1" : "0";
			String noconsulta = (String) det1.findFieldByNameCreate("_NOCONSULTA").getValue();
			if (noconsulta == null) {
				noconsulta = "0";
			}
			if ((det1.getResponse().getCode().compareTo(GeneralResponse.OK) == 0) && (finan.compareTo("1") != 0) && (noconsulta.compareTo("1") != 0)) {
				FitbankLogger.getLogger().debug("Mantenimiento previo a una consulta");
				return this.query();
			}
			return "";
		} catch (Exception e) {
			e.printStackTrace();
			util.addErrorMessage(e);
			return "";
		}
	}

	public void setHttpSession(HttpSession httpSession) {
		this.httpSession = httpSession;
	}

	public void setRequest(ServletRequest request) {
		this.request = request;
	}

	public String test() {
		FacesUtil util = new FacesUtil(this, this.request);
		try {
			Detail det = this.getDetail();
			util.getSession().setAttribute("detXML", det.toErrorXml());
			util.addMessage("Bind OK");
		} catch (Exception e) {
			e.printStackTrace();
			util.addErrorMessage(e);
		}
		return "";

	}

	protected void validateResponse(GeneralResponse pResponse, ServletRequest pRequest) throws FitbankException {
		FacesUtil util = new FacesUtil();
		util.setRequest(pRequest);
		util.setDm(this);
		if (pResponse.getCode().compareTo(GeneralResponse.OK) != 0) {
			util.getSession().setAttribute("_responseCode", pResponse.getCode());
			throw new FitbankException(pResponse.getCode(), pResponse.getUserMessage());
		} else {
			util.getSession().setAttribute("errorMSG", pResponse.getUserMessage());
			util.addMessage(pResponse.getUserMessage());

		}
	}

}
