package com.fp.sessionbeans.ejb.cobis;

import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.Types;

import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.fp.ach.exception.AchException;
import com.fp.dto.save.SaveRequest;
import com.fp.sessionbeans.ejb.interfaces.ContabilizaCobisLocal;

/**
 * Session Bean utilitario para obtener informacion de cobis.
 *
 * @author Jorge Vaca.
 * @version 2.1
 */
@Stateless
@TransactionManagement(value = TransactionManagementType.BEAN)
public class ContabilizaCobisBean implements ContabilizaCobisLocal {

    /**
     * Metodo que ejecuta la transaccion en cobis.
     *
     * @param pSaveRequest Mensaje de entrada de ejecucion de la transaccion.
     * @param pAmount Monto de la afectacion contable.
     * @param pCurrency MOneda de la afectacion contable.
     * @param pProfile Perfil de afectacion contable.
     * @param pServer Codigo de servidor cobis con el que se ejecuta una
     *            transaccion.
     * @param pOffcie Codigo de oficina cobis con la que se ejecuta la
     *            transaccion.
     * @throws Exception
     */
    @SuppressWarnings("deprecation")
    @Override
    public void process(SaveRequest pSaveRequest, BigDecimal pAmount, Integer pCurrency, String pProfile,
            String pServer, Integer pOffcie, Integer pArea) throws Exception {
        EntityManagerFactory emf = null;
        EntityManager em = null;
        Connection c = null;
        CallableStatement cs = null;
        try {
            emf = Persistence.createEntityManagerFactory("cobis");
            em = emf.createEntityManager();
            //c = ((Session) em.getDelegate()).connection();
            // c.setTransactionIsolation(Connection.TRANSACTION_NONE);
            cs = c.prepareCall("{ call maia..sp_contabiliza(?,?,?,?,?,?,?,?,?,?,?) }");
            this.fillParameters(pSaveRequest, cs, pAmount, pCurrency, pProfile, pServer, pOffcie, pArea);
            // ejecutar el SP
            cs.execute();
            String cresultado = cs.getString(10);
            if (cresultado.compareTo("0") == 0) {
                return;
            }
            String textoerror = cs.getString(11);
            throw new AchException(cresultado, textoerror);
        } catch (Exception e) {
            throw e;
        } finally {
            if (cs != null) {
                cs.close();
            }
            if (em != null) {
                em.clear();
                em.close();
                emf.close();
            }
        }
    }

    /**
     * Metodo que fija los parametros necesarios para ejecutar el proceso de
     * base.
     *
     * @param pSaveRequest Mensaje de entrada de ejecucion de la transaccion.
     * @param pEntryDetail Datos del registro a procesar.
     * @param cs Referencia a CallableStatement
     * @throws Exception
     */
    private void fillParameters(SaveRequest pSaveRequest, CallableStatement cs, BigDecimal pAmount, Integer pCurrency,
            String pProfile, String pServer, Integer pOffcie, Integer pArea) throws Exception {
        cs.setString(1, pServer); // Nombre del servidor COBIS
        cs.setInt(2, pOffcie); // Oficina COBIS
        cs.setString(3, pSaveRequest.getUser()); // Usuario
        cs.setString(4, "127.0.0.1"); // Terminal
        cs.setBigDecimal(5, pAmount); // MOnto de la transacion
        cs.setInt(6, pCurrency);// MOneda 0 = U.S.
        cs.setString(7, pProfile);// Fecha proceso de Cobis
        cs.setInt(8, pArea);// area
        cs.setString(9, "");// Glosa del comprobante
        cs.setString(10, ""); // Codigo de resultado
        cs.setString(11, ""); // Texto de resultado
        // parametro de salida
        cs.registerOutParameter(10, Types.CHAR);
        cs.registerOutParameter(11, Types.CHAR);
    }

    /**
     * Metodo que se encarga de contabilizar valores del repositorio unico.
     *
     * @param pSaveRequest Datos del request original.
     * @param pServer Nombre del servidor cobis.
     * @param pOffcie Codigo de oficina.
     * @param pDate Fecha de contabilizacion.
     * @param pUser Codigo de usuario.
     * @param pTransaction Codigo de transaccion cobis 2804,
     * @param pOperation Codigo de operacion "C"
     * @param pProduct Codigo de producto ach 33
     * @throws Exception
     */
    @SuppressWarnings("deprecation")
    @Override
    public void processRepository(SaveRequest pSaveRequest, String pServer, Integer pOffcie, Date pDate, String pUser,
            Integer pTransaction, String pOperation, Integer pProduct) throws Exception {
        EntityManagerFactory emf = null;
        EntityManager em = null;
        Connection c = null;
        CallableStatement cs = null;
        try {
            emf = Persistence.createEntityManagerFactory("cobis");
            em = emf.createEntityManager();
            //c = ((Session) em.getDelegate()).connection();
            // c.setTransactionIsolation(Connection.TRANSACTION_NONE);
            cs = c.prepareCall("{ call maia..sp_afecta_conta_ach(?,?,?,?,?,?,?,?,?) }");
            this.fillParameters(cs, pServer, pOffcie, pDate, pUser, pTransaction, pOperation, pProduct);
            // ejecutar el SP
            cs.execute();
            c.close();
            String cresultado = cs.getString(8);
            if (cresultado.compareTo("0") == 0) {
                return;
            }
            String textoerror = cs.getString(9);
            throw new AchException(cresultado, textoerror);
        } catch (Exception e) {
            throw e;
        } finally {
            if (cs != null) {
                cs.close();
            }
            if (em != null) {
                em.clear();
                em.close();
                emf.close();
            }
        }
    }

    /**
     * Fija parametros en el CallableStatement.
     * @param cs  Objeto utilizado para la ejecucion del sp de cobis.
     * @param pServer Nombre del servidor cobis.
     * @param pOffcie Codigo de oficina.
     * @param pDate Fecha de contabilizacion.
     * @param pUser Codigo de usuario.
     * @param pTransaction Codigo de transaccion cobis 2804,
     * @param pOperation Codigo de operacion "C"
     * @param pProduct Codigo de producto ach 33
     * @throws Exception
     */
    private void fillParameters(CallableStatement cs, String pServer, Integer pOffcie, Date pDate, String pUser,
            Integer pTransaction, String pOperation, Integer pProduct) throws Exception {
        cs.setString(1, pServer); // Nombre del servidor COBIS
        cs.setInt(2, pOffcie); // Oficina COBIS
        cs.setDate(3, pDate); // Fecha
        cs.setString(4, pUser); // Usuario
        cs.setInt(5, pTransaction); // Codigo de transaccion
        cs.setString(6, pOperation);// Codigo de operacion
        cs.setInt(7, pProduct);// area
        cs.setString(8, ""); // Codigo de resultado
        cs.setString(9, ""); // Texto de resultado
        // parametro de salida
        cs.registerOutParameter(8, Types.CHAR);
        cs.registerOutParameter(9, Types.CHAR);
    }
}
