package com.fp.frontend.controller.armas.solicitud;

import java.math.BigDecimal;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.context.RequestContext;

import com.fp.dto.AbstractDataTransport;
import com.fp.dto.Request;
import com.fp.dto.Response;
import com.fp.dto.save.DtoSave;
import com.fp.frontend.controller.AbstractController;
import com.fp.frontend.controller.alfresco.AlfrescoController;
import com.fp.frontend.controller.armas.funcionalidad.CargaController;
import com.fp.frontend.controller.armas.parametros.CentroControlArmasController;
import com.fp.frontend.controller.armas.parametros.IngresoDatosTipoTramite;
import com.fp.frontend.controller.armas.parametros.TarmCentroControlJurController;
import com.fp.frontend.controller.pcustomer.PersonAddressController;
import com.fp.frontend.controller.pcustomer.PersonDetailController;
import com.fp.frontend.controller.pgeneral.date.TgeneNotAccountingDayController;
import com.fp.frontend.controller.pgeneral.gene.CatalogDetailController;
import com.fp.frontend.controller.pgeneral.gene.ParametersController;
import com.fp.frontend.helper.MessageHelper;
import com.fp.frontend.utility.MsgControlArmas;
import com.fp.frontend.utility.MsgGeneral;
import com.fp.persistence.parmas.fun.TarmCarga;
import com.fp.persistence.parmas.param.TarmCentroControl;
import com.fp.persistence.parmas.param.TarmCentroControlJur;
import com.fp.persistence.parmas.param.TarmTramite;
import com.fp.persistence.parmas.soli.TarmAgenciaArma;
import com.fp.persistence.parmas.soli.TarmDocumentoHabilitante;
import com.fp.persistence.parmas.soli.TarmSolicitud;
import com.fp.persistence.parmas.soli.TarmSolicitudAgenciaSucursal;
import com.fp.persistence.parmas.soli.TarmSolicitudArmas;
import com.fp.persistence.parmas.soli.TarmSolicitudRequisitos;
import com.fp.persistence.parmas.soli.TarmSolicitudTramite;
import com.fp.persistence.parmas.soli.TarmSolicitudTramiteKey;
import com.fp.persistence.pcustomer.gene.TcustPersonAddress;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pgeneral.gene.TgeneCatalogDetail;
import com.fp.persistence.pgeneral.gene.TgeneParameters;
import com.fp.persistence.pgeneral.safe.TsafeUserDetail;

/**
 * Clase controladora para la verificacion de los requisitos del tramite.
 *
 * @author C.P.
 * @version 2.1
 */
@SuppressWarnings("serial")
@ManagedBean
@ViewScoped
public class VerificacionRequisitosSolicitudController extends AbstractController<AbstractDataTransport> {

    /**
     * codigo del flujo
     */
    private String codigoSolicitud;
    private BigDecimal costoTramite = new BigDecimal("0");
    private BigDecimal numeroArmas = new BigDecimal("0");
    private BigDecimal numeroDocuementos = new BigDecimal("0");
    private BigDecimal cantidad = new BigDecimal("0");
    private String numeroTramite;
    private String tipoautorizacion;
    private String usoactividad;
    private Boolean btnGuardar = Boolean.FALSE;
    private Boolean requiereCustodiosBln;
    private Boolean requiereNoSolAucpBln;

    private List<TarmSolicitudArmas> armas;
    /**
     * Fecha de atencion del proximo tramite
     */
    private java.util.Date fechaAtencionTramite;
    /**
     * Bandera de tipo booleano para indicar si se habilita el boton de
     * completar tarea
     */
    private Boolean isEnableCompletarTarea = Boolean.FALSE;

    /**
     * Codigo de la tabla TGENECATALOGDETAIL para indicar que el tipo de costo
     * es Total
     */
    private final String TIPOCOSTOTOTAL = "2";
    /**
     * Codigo de la tabla TGENECATALOGDETAIL para indicar que el registro a
     * buscarse eN CATALOG es COSTOCUSTODIO
     */
    private final String CODIGOCOSTOCUSTODIO = "COSTOCUSTODIO";

    /**
     * Variable del tipo TarmSolicitudnal
     */
    private TarmSolicitud recordsolicitud;
    /**
     * Variable del tipo TarmSolicitudnal
     */
    TarmSolicitudTramite recordSolicitudTra;

    /**
     * Variable del tipo TgeneCatalogDetail(catalogo del tipo de documento)
     */
    private TgeneCatalogDetail nombreDocumento;
    /**
     * Variable del tipo TgeneCatalogDetail(catalogo del tramite)
     */
    private TgeneCatalogDetail nombreTramite;
    /**
     * Variable del tipo TgeneCatalogDetail(catalogo de la categoria)
     */
    private TgeneCatalogDetail nombreCategoria;
    /**
     * Variable del tipo TgeneCatalogDetail(catalogo del uso actividad del
     * tramite)
     */
    private TgeneCatalogDetail nombreUsoActividad;
    /**
     * lista del catalogo de las acciones (Aceptar o rechazar)
     */
    private List<TgeneCatalogDetail> laccion;
    /**
     * atributo para el estado de la solicitud aprobado o anulado
     */
    private String estado;
    /**
     * observacion de la solicitud
     */
    private String observacion;
    /**
     * controlador de los requisitos de la solicitud
     */
    @ManagedProperty(value = "#{solicitudRequisitosController}")
    private SolicitudRequisitosController requisitos;
    /**
     * controlador si aprueban la solicitud se genera el numero de tramite
     */
    @ManagedProperty(value = "#{solicitudTramiteController}")
    private SolicitudTramiteController solicitudTramiteController;
    /**
     * controlador de la solicitud
     */
    @ManagedProperty(value = "#{solicitudArmasController}")
    private SolicitudArmasController solicitud;
    /**
     * controlador para el manejo de los archivos del alfresco
     */
    @ManagedProperty(value = "#{alfrescoController}")
    private AlfrescoController alfrescoController;
    /**
     * Controlador del tramite
     */
    @ManagedProperty(value = "#{ingresoDatosTipoTramite}")
    private IngresoDatosTipoTramite tramite;

    /**
     * Propiedad usada para el manejo del centro de control de armas
     */
    @ManagedProperty(value = "#{centroControlArmasController}")
    private CentroControlArmasController centroControlArmasController;

    /**
     * Controlador de Documento Habilitante
     */
    @ManagedProperty(value = "#{documentoHabilitanteController}")
    private DocumentoHabilitanteController documentoHabilitanteController;

    /**
     * Controlador que maneja las armas asociadas a las agencias
     */
    @ManagedProperty(value = "#{agenciaArmaController}")
    private AgenciaArmaController agenciaArma;

    /**
     * Referencia al Centro de control;
     */
    private TarmCentroControl centroControl = new TarmCentroControl();

    /**
     * Nombre de la Institucion
     */
    private String nombreInstitucion;

    public VerificacionRequisitosSolicitudController() throws Exception {
        super(AbstractDataTransport.class);
    }

    /**
     * Controlador que maneja cargas para previa importacion
     */
    @ManagedProperty(value = "#{cargaController}")
    private CargaController cargaController;

    @PostConstruct
    private void postconstruct() {

        try {
            super.startQuery();
            fechaAtencionTramite = new Date(new java.util.Date().getTime());
            codigoSolicitud = this.getMfilters().get("codigoSolicitud");

            int numArmasInt = TarmSolicitudArmasController.getNumeroArmasPorSolicitud(codigoSolicitud);

            numeroArmas = new BigDecimal(numArmasInt);
            habilitarIngresoCustodios();
            this.getMfilters().clear();
            this.getRequisitos().getMfilters().clear();
            this.getSolicitud().getMfilters().clear();
            this.getSolicitudTramiteController().getMfilters().clear();
            this.getTramite().getMfilters().clear();
            this.init();
            cargaDatos();
            mostrarNoSolAucp();
        } catch (Exception e) {
            e.printStackTrace();
            MessageHelper.setMessageError(e);
        }
    }

    /**
     * Metodo que se encarga de determinar si se requiere o no ingresar numero
     * de custodios
     */
    private void habilitarIngresoCustodios() {
        TgeneParameters minArmasReqCustodiaObj = ParametersController.find("NUMERO.ARMAS.FLUJO", "1");
        if (numeroArmas.compareTo(minArmasReqCustodiaObj.getNumbervalue()) <= 0) {
            requiereCustodiosBln = Boolean.FALSE;
        } else {
            requiereCustodiosBln = Boolean.TRUE;
        }
    }

    /**
     * Metodo que se encarga de mostrar el numero de solicitud aucp o no si la
     * categoria es igual previa importacion
     */
    private void mostrarNoSolAucp() {
        // CATEGORIA 14 PREVIA IMPORTACION
        TarmTramite tarmTramite = TarmTramiteController.find(this.recordsolicitud.getCtramite().toString());
        if (tarmTramite.getCategoria().equals("14")) {
            requiereNoSolAucpBln = Boolean.TRUE;
        } else {
            requiereNoSolAucpBln = Boolean.FALSE;
        }

    }

    /**
     * Metodo para obtener los datos iniciales
     *
     * @throws Exception
     */
    public void cargaDatos() throws Exception {
        //solicitud(Persona tramite)
        recordsolicitud = SolicitudArmasController.find(codigoSolicitud);
        this.armas = TarmSolicitudArmasController.findPorCSolicitud(this.codigoSolicitud);
        //Comprobando que tenga tramites anteriores caducados
        //Obteniendo la solicitud
        TarmSolicitud solicitud = SolicitudController.findSolicitudxcodsolicitud(this.codigoSolicitud);

//    	if(solicitud!=null){
        //Obteniendo el tramite de la solicitud
//        	TarmTramite tramite=TarmTramiteController.find(solicitud.getCtramite().toString());
        //Validando que el tipo de tramite sea de Renovacion
//        	if(tramite.getTipotramite().equalsIgnoreCase("3")){
        //Obteniendo los documentos habilitantes        		
//        		List<TarmDocumentoHabilitante> documentosPersona=DocumentoHabilitanteController.findPorPersoncode(solicitud.getPersoncode().toString());
//        		List<TarmDocumentoHabilitante> documentosTramite=new ArrayList<TarmDocumentoHabilitante>();
//        		List<TarmTramite> tramites=new ArrayList<TarmTramite>();
//        		for (TarmDocumentoHabilitante d : documentosPersona) {
//    				//Obteniendo el tramite del documento
//        			TarmTramite t=TarmTramiteController.find(d.getCtramite().toString());
//        			if(t!=null && t.getTipoautorizacion().equalsIgnoreCase(tramite.getTipoautorizacion())
//        					&& t.getCategoria().equalsIgnoreCase(tramite.getCategoria())
//        					&& t.getUsoactividad().equalsIgnoreCase(tramite.getUsoactividad())){
//        				tramites.add(t);
//        				documentosTramite.add(d);
//        			}        			
//    			}
        //Obteniendo el documento de mayor fecha(ultimo documento)
//        		TarmDocumentoHabilitante ultimoDocumento=documentosTramite.get(0);
//        		TarmTramite ultimoTramite=tramites.get(0);
//        		
//        		for (int i = 1; i < documentosTramite.size(); i++) {
//					if(documentosTramite.get(i).getFechaemision().after(ultimoDocumento.getFechaemision())){
//						ultimoDocumento=documentosTramite.get(i);
//						ultimoTramite=tramites.get(i);
//					}
//				}
        //Verificando que el documento este caducado
//        		Date fechaActual=new Date(Calendar.getInstance().getTimeInMillis());
//        		if(ultimoDocumento.getFechaexpiracion().before(fechaActual)){
//        			//Calculando el valor de la multa
//        			Long MILISEGUNDOS_POR_DIA = 24 * 60 * 60 * 1000L; //Milisegundos al dia 
//        			java.util.Date fechaActual2=Calendar.getInstance().getTime();        			     
//        			 
//        			Calendar calendar=Calendar.getInstance();
//        			calendar.setTime(ultimoDocumento.getFechaexpiracion());
//        			java.sql.Date fechaAnterior = new java.sql.Date(calendar.getTimeInMillis());
//
//        			Long diferenciaDias = ( fechaActual2.getTime() - fechaAnterior.getTime() )/MILISEGUNDOS_POR_DIA;        			 
//        			Double valorMulta=0.0;
//        			Double multaConfig=0.0;
//        			if(tramite.getMulta()!=null){
//        				multaConfig=Double.parseDouble(tramite.getMulta().toString());
//        			}        			
//        			
//        			//Autorizacion
//        			if(ultimoTramite.getTipoautorizacion().equalsIgnoreCase("1")){
//        				if(diferenciaDias>30){        					
//        					valorMulta=multaConfig*((diferenciaDias-30)/365);
//        				}
//        					
//        			//Permiso
//        			}else if(ultimoTramite.getTipoautorizacion().equalsIgnoreCase("6")){
//        				//Obteniendo las armas
//        				this.armas= TarmSolicitudArmasController.findPorCSolicitud(this.codigoSolicitud);
//        				int totalArmas=this.armas.size();
//        				valorMulta=(multaConfig/12)*(diferenciaDias/30)*totalArmas;        				        				
//        			}
//        			
//        			this.recordsolicitud.setMulta(new BigDecimal(valorMulta.toString()));
//        			this.recordsolicitud.setMulta(BigDecimal.ZERO);
//        		}
//        	}    		
//    	}
        //nombre documento
        nombreDocumento = CatalogDetailController.findxCodigoCodcatalogo(recordsolicitud.getModifiedData().get("identificationcatalog").toString(), recordsolicitud.getModifiedData().get("identificationcatalogcode").toString());
        if (nombreDocumento != null) {
            //Tramite
            nombreTramite = CatalogDetailController.findxCodigoCodcatalogo(recordsolicitud.getModifiedData().get("tipoautorizacion").toString(), recordsolicitud.getModifiedData().get("tipoautorizacioncodigo").toString());
            nombreCategoria = CatalogDetailController.findxCodigoCodcatalogo(recordsolicitud.getModifiedData().get("categoria").toString(), recordsolicitud.getModifiedData().get("categoriacodigo").toString());
            nombreUsoActividad = CatalogDetailController.findxCodigoCodcatalogo(recordsolicitud.getModifiedData().get("usoactividad").toString(), recordsolicitud.getModifiedData().get("usoactividadcodigo").toString());
            //lista de requisitos
            requisitos.getMfilters().put("pk.csolicitud", codigoSolicitud);
            requisitos.query();
            //variable para validar el boton 
            requisitos.setAuxBotonVerificacion(Boolean.TRUE);
            for (TarmSolicitudRequisitos item : requisitos.getLrecord()) {
                if (item.getEstadovalidacion() != null && item.getEstadovalidacion().equals("Y")) {
                    item.modifiedData().put("estado", Boolean.TRUE);
                } else {
                    //item.modifiedData().put("estado", Boolean.FALSE);
                    requisitos.setAuxBotonVerificacion(Boolean.FALSE);
                }
            }
            this.obtenerCentroControl(solicitud);
            //valida lo del combo del flujo
            validacioComboFlujo();
        } else {
            MessageHelper.setMessageError("NO EXISTE SOLICITUD PENDIENTE");
        }
    }

    /**
     * Incializa el controlador, cuando se esta utilizando una pagina que utliza
     * el controlador.
     */
    @SuppressWarnings("unused")
    private void init() {
        TgeneParameters parametersAutorizacion = ParametersController.find("CODIGO.GUIA.LIBRETRANSITO", "1"); //4
        TgeneParameters parametersUsoActividad = ParametersController.find("CODIGO.FUEGOS.PIROTECNICOS", "1");//17
        tipoautorizacion = parametersAutorizacion.getTextvalue();
        usoactividad = parametersUsoActividad.getTextvalue();
    }

    /**
     * Metodo para cargar actualizar la solicitud validando que el numero de
     * custodio sea mayor a cero y cumpla con la condicion
     *
     * @throws Exception
     */
    public void cargarSolicitud() throws Exception {
        recordsolicitud.setFverificarequisitos(new Date(new java.util.Date().getTime()));
        if (codigoAceptado().equals(estado)) {
            //validacion drf Tramite es Guia de Libre Transito y el Uso/Actividad es diferente a Fuegos Pirotecnicos, el campo No. Custodios sea mayor que cero.
            if (recordsolicitud.getModifiedData().get("tipoautorizacion").toString().equals(tipoautorizacion)
                    && !recordsolicitud.getModifiedData().get("usoactividad").toString().equals(usoactividad)) {
                if (recordsolicitud.getNumerocustodios() < 0) {
                    MessageHelper.setMessageError("EL N\u00DAMERO DE CUSTODIOS DEBE SER POSITIVO");
                    return;
                }
            }
            recordsolicitud.setObservacion(observacion);
            recordsolicitud.setEstado(estado);
            recordsolicitud.setEstadocodigo("ESTADOSOLICITUD");
            solicitud.update(recordsolicitud);
        } else {
            recordsolicitud.setObservacion(observacion);
            recordsolicitud.setEstadocodigo("ESTADOSOLICITUD");
            recordsolicitud.setEstado(estado);//ACCION        	 
            solicitud.update(recordsolicitud);
        }

    }

    /**
     * Obtiene el centro de control segun usurio logeado.
     *
     * @param solicitud
     * @throws Exception
     *
     */
    private void obtenerCentroControl(TarmSolicitud solicitud) throws Exception {

        this.centroControl = CentroControlArmasController.findPorCodigo(solicitud.getCcentrocontrol());
        this.setNombreInstitucion(CatalogDetailController.findxCodigoCodcatalogo(centroControl.getNombreinstitucion(), centroControl.getNombreinstitucioncodigo()).getDescription());

    }

    /**
     * Metodo para cargar el registro de la solicitud tramite en la lista new
     *
     * @throws Exception
     */
    public void cargaDatosSolicitudTramite() throws Exception {
        recordSolicitudTra = new TarmSolicitudTramite();
        TarmSolicitudTramiteKey pk = new TarmSolicitudTramiteKey();
        // Setear el valor a pagar en la tabla tramite        	
        TarmTramite tramiteActual = IngresoDatosTipoTramite.find(recordsolicitud.getCtramite().toString());
        List<TarmDocumentoHabilitante> ldocumentos = this.documentoHabilitanteController.findXSolicitudNueva(codigoSolicitud);
        // Valor a pagar por concepto de custudios
        BigDecimal valorAPagarArmas = new BigDecimal("0");
        /*if(tramiteActual.getTipocosto().equals("2")){
        		valorAPagarArmas = tramiteActual.getCosto();
        	}
        	else{  
//        		numeroArmas = new BigDecimal(TarmSolicitudArmasController.getNumeroArmasPorSolicitud(codigoSolicitud));
        		BigDecimal costoPorArma = tramiteActual.getCosto();        		
        		valorAPagarArmas = costoPorArma.multiply(numeroArmas);       		           		
        	} */
        if (tramiteActual.getTipocosto().equals("2")) {
            valorAPagarArmas = tramiteActual.getCosto();
        } else if (numeroArmas != null && numeroArmas.compareTo(new BigDecimal(0)) > 0) {
            numeroArmas = new BigDecimal(TarmSolicitudArmasController.getNumeroArmasPorSolicitud(codigoSolicitud));
            this.cantidad = this.numeroArmas;
            BigDecimal costoPorArma = tramiteActual.getCosto();
            valorAPagarArmas = costoPorArma.multiply(numeroArmas);
        } else {
            numeroDocuementos = new BigDecimal(ldocumentos.size());
            this.cantidad = this.numeroDocuementos;
            BigDecimal costoPorArma = tramiteActual.getCosto();
            valorAPagarArmas = costoPorArma.multiply(numeroDocuementos);
        }
        recordSolicitudTra.setValortramitearmas(valorAPagarArmas);
        // Valor a pagar por concepto de custudios
        BigDecimal numeroCustodios = new BigDecimal("0");

        if (recordsolicitud.getNumerocustodios() != null) {
            numeroCustodios = new BigDecimal(recordsolicitud.getNumerocustodios());
        }
        BigDecimal numeroDiasCustodios = new BigDecimal("0");
        if(recordsolicitud.getNumerodiascustodios()!= null){
            numeroDiasCustodios = new BigDecimal(recordsolicitud.getNumerodiascustodios());
        }
        BigDecimal costoCustodio = new BigDecimal("0");
        if (tramiteActual.getCostocustodio() != null) {
            costoCustodio = tramiteActual.getCostocustodio();
        }
        /**
         * AGREGAMOS A LA MULTIPLICACION EL NUMERO DE DIAS DE LOS CUSTODIOS
         */
        BigDecimal valorAPagarCustodio = costoCustodio.multiply(numeroCustodios).multiply(numeroDiasCustodios);
        recordSolicitudTra.setValorcustodios(valorAPagarCustodio);
        // Valor a pagar por concepto de multas
        BigDecimal multa = new BigDecimal("0");
        if (recordsolicitud.getMulta() != null) {
            multa = recordsolicitud.getMulta();
        }
        recordSolicitudTra.setValormulta(multa);
        // Sumamos el valor de a pagar de las armas, custodios y multa 
        costoTramite = valorAPagarArmas.add(valorAPagarCustodio).add(multa);

        recordSolicitudTra.setValorapagar(costoTramite);
        pk.setCsolicitud(codigoSolicitud);
        pk.setCtramite(Long.valueOf(recordsolicitud.getModifiedData().get("pk").toString()));
        recordSolicitudTra.setPk(pk);
        numeroTramite = recordsolicitud.getNumerosolicitud().replace("SOL", "TRA");
        recordSolicitudTra.setNumerotramite(numeroTramite);
        recordSolicitudTra.setEstadotramite(codigo("CODIGO.REG.ESTADOSOLICITUD"));//CODIGO.REG.ESTADOSOLICITUD  REG
        recordSolicitudTra.setEstadotramitecodigo("ESTADOSOLICITUD");
        solicitudTramiteController.update(recordSolicitudTra);
    }

    /**
     * Metodo para generar el numero de tramite
     */
    public void generaNumeroTramite() {
        if (recordsolicitud.getModifiedData().get("tipoautorizacion").toString().equals(tipoautorizacion)
                && !recordsolicitud.getModifiedData().get("usoactividad").toString().equals(usoactividad)) {
            if (recordsolicitud.getNumerocustodios() == null || recordsolicitud.getNumerocustodios() < 0) {
                MessageHelper.setMessageError("EL N\u00DAMERO DE CUSTODIOS DEBE SER POSITIVO");
                return;
            }
        }
        numeroTramite = recordsolicitud.getNumerosolicitud().replace("SOL", "TRA");
        validacioComboFlujo();
    }

    public void validacioComboFlujo() {
        try {
            TgeneParameters tgeneparam = ParametersController.find("CODIGO.AR", "1");
            laccion = CatalogDetailController.find("ESTADOSOLICITUD", tgeneparam.getTextvalue());
            TgeneCatalogDetail catalogDetail = null;
            for (TgeneCatalogDetail item : laccion) {
                if (requisitos.getAuxBotonVerificacion()) {
                    if (!item.getPk().getCatalog().equals(codigoAceptado())) {
                        catalogDetail = item;
                        estado = "APB";
                    }
                } else if (item.getPk().getCatalog().equals(codigoAceptado())) {
                    catalogDetail = item;
                    estado = "ANU";
                }
            }
            laccion.remove(catalogDetail);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Metodo para finalizar la tarea del flujo
     */
    @Override
    public void completarTarea() {

        try {
            Request request = callerhelper.getRequest();
            // limpiar request para finalizar la tarea.
            super.cleanRequest(request);
            request.modifiedData().put("TID", tid);
            request.modifiedData().put("csolicitud", recordsolicitud.getPk());
            Map<String, Object> datosmail = new HashMap<String, Object>();
            if (codigoAceptado().equals(estado)) {
                request.modifiedData().put("BPMStatus", bpmDataStatus == null ? "A" : bpmDataStatus); // A,D,R
                datosmail.put("razonsocial", recordsolicitud.getModifiedData().get("nombre"));
                datosmail.put("tipoTramite", nombreTramite.getDescription());
                datosmail.put("actividad", nombreUsoActividad.getDescription());
                datosmail.put("categoria", nombreCategoria.getDescription());
                datosmail.put("numeroTramite", numeroTramite);
                datosmail.put("costoTramite", costoTramite);
                datosmail.put("abrevMoneda", ParametersController.find("ABREVMONEDA", "1").getTextvalue());
                datosmail.put("nombreDelBanco", ParametersController.find("BANCODEPOSITO", "1").getTextvalue());
                datosmail.put("cuentaCorriente", ParametersController.find("CUENTADEPOSITO", "1").getTextvalue());
                datosmail.put("diasLaborablesDeposito", ParametersController.find("DIASDEPOSITO", "1").getNumbervalue().toString());
                TsafeUserDetail userDetailObj = (TsafeUserDetail) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("TSAFEUSERDETAIL");
                TcustPersonDetail personDetailObj = PersonDetailController.find(userDetailObj.getPk().getPersoncode().toString());
                // Datos del funcionario que valida
                datosmail.put("funcionario", personDetailObj.getName());
                datosmail.put("grado", personDetailObj.getMilitarygrade() == null ? "" : personDetailObj.getMilitarygrade());
                // Centro de control de armas
                TarmCentroControl centroControlObj = CentroControlArmasController.findPorCodigo(solicitud.getRecord().getCcentrocontrol());
                datosmail.put("nombreCCAsignado", centroControlObj.getModifiedData().get("desnombreinstitucion"));
                datosmail.put("nombreCCA", centroControlObj.getModifiedData().get("desnombreinstitucion")); //Pendiente
                if (recordsolicitud.getModifiedData().get("tipoautorizacion") != null && costoTramite.compareTo(new BigDecimal("0")) == 0) {
                    // En el caso de permisos enviamos una notificacion al cliente con algunos parametros adicionales		
                    if (recordsolicitud.getModifiedData().get("tipoautorizacion").toString().equalsIgnoreCase("6")) {
                        generarFechaProximoTramite();
                        SimpleDateFormat sdf = new SimpleDateFormat(MsgGeneral.getProperty("dateformat"));
                        datosmail.put("fechaGenerada", sdf.format(fechaAtencionTramite));
                        datosmail.put("nombreCCACliente", obtenerCentroControlSolicitante());
                    }
                }
            } else {
                datosmail.put("razonsocial", recordsolicitud.getModifiedData().get("nombre"));
                datosmail.put("nombre", recordsolicitud.getModifiedData().get("nombre"));
                datosmail.put("numerosolicitud", recordsolicitud.getNumerosolicitud());
                SimpleDateFormat fm = new SimpleDateFormat("dd-MM-yyyy");
                datosmail.put("fechasolicitud", fm.format(recordsolicitud.getFregistro()));
                datosmail.put("observaciones", observacion);
                //grado funcionario de la persona logeada
                TsafeUserDetail userDetailObj = (TsafeUserDetail) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("TSAFEUSERDETAIL");
                TcustPersonDetail personDetailObj = PersonDetailController.find(userDetailObj.getPk().getPersoncode().toString());
                datosmail.put("grado", personDetailObj.getMilitarygrade());
                datosmail.put("funcionario", personDetailObj.getName());
                // Centro de control de armas
                TarmCentroControl centroControlObj = CentroControlArmasController.findPorCodigo(solicitud.getRecord().getCcentrocontrol());
                String nombreCentroControl = CatalogDetailController.findxCodigoCodcatalogo(centroControlObj.getNombreinstitucion(),
                        centroControlObj.getNombreinstitucioncodigo()).getDescription();
                datosmail.put("centrocontrol", nombreCentroControl);
                request.modifiedData().put("BPMStatus", bpmDataStatus == null ? "D" : bpmDataStatus); // A,D,R				
            }

            datosmail.put("costoTramite", costoTramite);
            request.modifiedData().put("datosmail", datosmail);
            request.modifiedData().put("BPMObs", bpmDataComment == null ? "OK" : bpmDataComment);

            Response resp = callerhelper.executeSave(request);

            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                MessageHelper.setMessageInfo(resp);
                if (estado.equalsIgnoreCase("ANU")) {
                    saveAnularSolicitud();
                }
                RequestContext.getCurrentInstance().execute("Maia.refreshusertasks()");
            } else {
                MessageHelper.setMessageError(resp);
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    public void saveAnularSolicitud() {
        try {
            // CATEGORIA 14	PREVIA IMPORTACION
            TarmTramite tarmTramite = TarmTramiteController.find(this.solicitud.getRecord().getCtramite().toString());
            if (tarmTramite.getCategoria().equals("14")) {
                desasociarCargaSolicitud();
            }

            //Poner la solicitud en estado anulado
            recordsolicitud.setEstado("ANU");
            recordsolicitud.setAucp(null);
            solicitud.setRecord(recordsolicitud);
            solicitud.update();
            DtoSave dtoSolicitud = solicitud.getDtoSave();

            TarmSolicitudTramite solicitudTramiteObj = SolicitudTramiteController.findByCSolicitud(recordsolicitud.getPk());
            if (solicitudTramiteObj != null) {
                solicitudTramiteObj.setIsnew(false);
                solicitudTramiteObj.setEstadotramite("ANU");
                solicitudTramiteController.updateSolicitud(solicitudTramiteObj);
            }
            //Desasociar las armas en apertura de agencias y apertura de sucursales
            if (recordsolicitud.getCtramite() == 44 || recordsolicitud.getCtramite() == 48) {
                List<TarmSolicitudArmas> armasSolicitudList = RecepcionArmasController.findPorSolicitud(recordsolicitud.getPk());
                for (TarmSolicitudArmas armaObj : armasSolicitudList) {

                    // Codigo agencia de la solicitud
                    List<TarmSolicitudAgenciaSucursal> solicitudAgenciaLst = SolicitudAgenciaSucursalController.findPorSolicitud(recordsolicitud.getPk());
                    for (TarmSolicitudAgenciaSucursal solicitudAgenciaSucursalObj : solicitudAgenciaLst) {
                        String cAgencia = solicitudAgenciaSucursalObj.getPk().getCagencia().toString();
                        TarmAgenciaArma agenciaArmaObj = AgenciaArmaController.findByCArma(armaObj.getPk().getCarma(), cAgencia);
                        agenciaArma.setRecord(agenciaArmaObj);
                        agenciaArma.remove();
                    }
                }
            }

            DtoSave dtoSolicitudTramite = solicitudTramiteController.getDtoSave();
            DtoSave dtoAgenciaArma = agenciaArma.getDtoSave();

            HashMap<String, DtoSave> msave = new HashMap<String, DtoSave>();

            Request request = callerhelper.getRequest();
            super.cleanRequest(request);
            msave.put(solicitud.getBeanalias(), dtoSolicitud); // adicionar metadata de mantenimiento para cada tabla.
            msave.put(solicitudTramiteController.getBeanalias(), dtoSolicitudTramite);
            msave.put(agenciaArma.getBeanalias(), dtoAgenciaArma);

            request.setSaveTables(msave);
            Response resp = callerhelper.executeSave(request);
            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                solicitud.postCommit(resp);
                solicitudTramiteController.postCommit(resp);
                agenciaArma.postCommit(resp);
                MessageHelper.setMessageInfo(resp);
            } else {
                MessageHelper.setMessageError(resp);
            }

        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    /**
     * Genera la fecha disponible para el proximo tramite en el centro de
     * control de armas respectivo
     */
    public void generarFechaProximoTramite() {
        try {
            // Validamos si ya existe una fecha para realizar el proximo tramite
            TarmCentroControl centroControlObj = CentroControlArmasController.findPorCodigo(recordsolicitud.getCcentrocontrol());
            centroControlObj.isnew = false;
            Date fechaActual = new Date(Calendar.getInstance().getTimeInMillis());
            if (centroControlObj.getFechaproximotramite() == null || centroControlObj.getFechaproximotramite().before(fechaActual)) {
                fechaAtencionTramite = TgeneNotAccountingDayController.diasLaborablesPosterioresAUnaFecha(new java.util.Date(), 1);
            } else {
                fechaAtencionTramite = centroControlObj.getFechaproximotramite();
            }
            // Numero de armas de la solicitud
            List<TarmSolicitudArmas> armasList = RecepcionArmasController.findPorSolicitud(recordsolicitud.getPk());
            int numArmasSolicitud = armasList.size();
            int salvedad = 10;
            int capacidadCentroUltDia = 0;
            if (centroControlObj.getCuposlibresultimodia() != null) {
                capacidadCentroUltDia = centroControlObj.getCuposlibresultimodia();
            } else {
                capacidadCentroUltDia = centroControlObj.getTramitespordia();
            }
            // Si la capacidad del centro en el ultimo dia es mayor al numero de armas a revisarse
            if (numArmasSolicitud < capacidadCentroUltDia) {
                centroControlObj.setCuposlibresultimodia(capacidadCentroUltDia - numArmasSolicitud);
                centroControlArmasController.update(centroControlObj);
                centroControlArmasController.save();

            } else if ((numArmasSolicitud == capacidadCentroUltDia) || (numArmasSolicitud <= (capacidadCentroUltDia + salvedad))) {
                // Si la capacidad del centro es igual al numero de armas a revisarse o ajusta cupo con la salvedad
                centroControlObj.setCuposlibresultimodia(centroControlObj.getTramitespordia());
                java.util.Date newFechaAtencionTramite = TgeneNotAccountingDayController.diasLaborablesPosterioresAUnaFecha(fechaAtencionTramite, 1);
                centroControlObj.setFechaproximotramite(new java.sql.Date(newFechaAtencionTramite.getTime()));
                centroControlArmasController.update(centroControlObj);
                centroControlArmasController.save();

            } else {
                // Cociente y residuo para los casos donde se tiene 50 armas o mas a tramitarse
                int diasRequeridos = numArmasSolicitud / centroControlObj.getTramitespordia();
                // Requerido para el calculo de los cupos disponibles para el ultimo dia
                int residuoDiasRequeridos = numArmasSolicitud % centroControlObj.getTramitespordia();
                fechaAtencionTramite = TgeneNotAccountingDayController.diasLaborablesPosterioresAUnaFecha(fechaAtencionTramite, 1);
                java.util.Date newFechaAtencionTramite;

                centroControlObj.setCuposlibresultimodia(centroControlObj.getTramitespordia() - residuoDiasRequeridos);
                newFechaAtencionTramite = TgeneNotAccountingDayController.diasLaborablesPosterioresAUnaFecha(fechaAtencionTramite, diasRequeridos);

                centroControlObj.setFechaproximotramite(new java.sql.Date(newFechaAtencionTramite.getTime()));
                centroControlArmasController.update(centroControlObj);
                centroControlArmasController.save();

            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

        }
    }

    /**
     * Metodo que devuelve el centro de control al que pertenece el cliente
     * dueno de la solicitud
     *
     * @throws Exception
     */
    private String obtenerCentroControlSolicitante() throws Exception {
        String institucionCentroControl = "";
        PersonAddressController personAddressController = new PersonAddressController();
        TcustPersonAddress tcustPersonAddres = personAddressController.findPrincipal(recordsolicitud.getPersoncode().toString());
        if (tcustPersonAddres != null && tcustPersonAddres.getProvincecode() != null) {
            TarmCentroControlJur centroControlJur = TarmCentroControlJurController.findxProvincia(tcustPersonAddres.getProvincecode());
            if (centroControlJur != null && centroControlJur.getCcentrocontrol() != null) {
                TarmCentroControl centroControl = CentroControlArmasController.findPorCodigo(centroControlJur.getCcentrocontrol());
                institucionCentroControl = CatalogDetailController.findxCodigoCodcatalogo(centroControl.getNombreinstitucion(), centroControl.getNombreinstitucioncodigo()).getDescription();
            } else {
                MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_error_laprovinciasinccontrol"));
                return MsgControlArmas.getProperty("msg_error_laprovinciasinccontrol");
            }
        } else {
            MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_error_notienedireccionprincipal"));
            return MsgControlArmas.getProperty("msg_error_notienedireccionprincipal");
        }

        return institucionCentroControl;
    }

    @Override
    public void save() {
        try {
            Request request = callerhelper.getRequest();
            // validamos si cargamos los datos cuando apruebe			
            if (codigoAceptado().equals(estado)) {
                cargaDatosSolicitudTramite();
            }
            HashMap<String, DtoSave> msave = new HashMap<String, DtoSave>();
            cargarSolicitud();
            // actualiza los requisitos
            DtoSave dtosavereq = requisitos.getDtoSave();
            dtosavereq.setReturnpk(true);
            dtosavereq.setPosition(1);
            msave.put(requisitos.getBeanalias(), dtosavereq);

            // inserta un nuevo registro en tarmSolicitudTramite
            DtoSave dtosavesol = solicitudTramiteController.getDtoSave();
            dtosavesol.setIsForm(true);
            dtosavesol.setReturnpk(true);
            dtosavesol.setPosition(2);
            msave.put(solicitudTramiteController.getBeanalias(), dtosavesol);

            // actualiza la solicitud el numero de custodios
            DtoSave dtossolicitud = solicitud.getDtoSave();
            dtosavesol.setIsForm(true);
            dtosavesol.setReturnpk(true);
            dtosavesol.setPosition(3);
            msave.put(solicitud.getBeanalias(), dtossolicitud);

            request.setSaveTables(msave);
            Response resp = callerhelper.executeSave(request);
            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                requisitos.postCommit(resp);
                solicitudTramiteController.postCommit(resp);
                // ocultarBotonInicioFlujo = false;
                MessageHelper.setMessageInfo(resp);
                btnGuardar = Boolean.TRUE;
                isEnableCompletarTarea = Boolean.TRUE;
            } else {
                // ocultarBotonInicioFlujo = true;
                MessageHelper.setMessageError(resp);
            }

        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    public void desasociarCargaSolicitud() {
        try {
            TarmCarga carga = CargaController.findByAUCP(solicitud.getRecord().getAucp());
            if (carga != null) {
                carga.setCsolicitud(null);
                cargaController.update(carga);
                cargaController.save();
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    public String codigoAceptado() throws Exception {
        TgeneParameters f = ParametersController.find("ACEPTADO", "1");//APB  ESTADOSOLICITUD
        return f.getTextvalue();
    }

    public String codigo(String codigo) throws Exception {
        TgeneParameters f = ParametersController.find(codigo, "1");//APB  ESTADOSOLICITUD
        return f.getTextvalue();
    }

    @Override
    protected void querydatabase() {
        try {

        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    @Override
    public void postCommit(Response response) throws Exception {
    }

    public String getCodigoSolicitud() {
        return codigoSolicitud;
    }

    public void setCodigoSolicitud(String codigoSolicitud) {
        this.codigoSolicitud = codigoSolicitud;
    }

    public SolicitudRequisitosController getRequisitos() {
        return requisitos;
    }

    public void setRequisitos(SolicitudRequisitosController requisitos) {
        this.requisitos = requisitos;
    }

    public TarmSolicitud getRecordsolicitud() {
        return recordsolicitud;
    }

    public void setRecordsolicitud(TarmSolicitud recordsolicitud) {
        this.recordsolicitud = recordsolicitud;
    }

    public TgeneCatalogDetail getNombreDocumento() {
        return nombreDocumento;
    }

    public void setNombreDocumento(TgeneCatalogDetail nombreDocumento) {
        this.nombreDocumento = nombreDocumento;
    }

    public TgeneCatalogDetail getNombreTramite() {
        return nombreTramite;
    }

    public void setNombreTramite(TgeneCatalogDetail nombreTramite) {
        this.nombreTramite = nombreTramite;
    }

    public TgeneCatalogDetail getNombreCategoria() {
        return nombreCategoria;
    }

    public void setNombreCategoria(TgeneCatalogDetail nombreCategoria) {
        this.nombreCategoria = nombreCategoria;
    }

    public TgeneCatalogDetail getNombreUsoActividad() {
        return nombreUsoActividad;
    }

    public void setNombreUsoActividad(TgeneCatalogDetail nombreUsoActividad) {
        this.nombreUsoActividad = nombreUsoActividad;
    }

    public SolicitudTramiteController getSolicitudTramiteController() {
        return solicitudTramiteController;
    }

    public void setSolicitudTramiteController(
            SolicitudTramiteController solicitudTramiteController) {
        this.solicitudTramiteController = solicitudTramiteController;
    }

    public List<TgeneCatalogDetail> getLaccion() {
        return laccion;
    }

    public void setLaccion(List<TgeneCatalogDetail> laccion) {
        this.laccion = laccion;
    }

    public SolicitudArmasController getSolicitud() {
        return solicitud;
    }

    public void setSolicitud(SolicitudArmasController solicitud) {
        this.solicitud = solicitud;
    }

    public AlfrescoController getAlfrescoController() {
        return alfrescoController;
    }

    public void setAlfrescoController(AlfrescoController alfrescoController) {
        this.alfrescoController = alfrescoController;
    }

    public IngresoDatosTipoTramite getTramite() {
        return tramite;
    }

    public void setTramite(IngresoDatosTipoTramite tramite) {
        this.tramite = tramite;
    }

    public BigDecimal getCostoTramite() {
        return costoTramite;
    }

    public void setCostoTramite(BigDecimal costoTramite) {
        this.costoTramite = costoTramite;
    }

    public BigDecimal getNumeroArmas() {
        return numeroArmas;
    }

    public void setNumeroArmas(BigDecimal numeroArmas) {
        this.numeroArmas = numeroArmas;
    }

    public String getNumeroTramite() {
        return numeroTramite;
    }

    public void setNumeroTramite(String numeroTramite) {
        this.numeroTramite = numeroTramite;
    }

    public String getEstado() {
        return estado;
    }

    public void setEstado(String estado) {
        this.estado = estado;
    }

    public String getObservacion() {
        return observacion;
    }

    public void setObservacion(String observacion) {
        this.observacion = observacion;
    }

    public String getTipoautorizacion() {
        return tipoautorizacion;
    }

    public void setTipoautorizacion(String tipoautorizacion) {
        this.tipoautorizacion = tipoautorizacion;
    }

    public String getUsoactividad() {
        return usoactividad;
    }

    public void setUsoactividad(String usoactividad) {
        this.usoactividad = usoactividad;
    }

    public Boolean getBtnGuardar() {
        return btnGuardar;
    }

    public void setBtnGuardar(Boolean btnGuardar) {
        this.btnGuardar = btnGuardar;
    }

    public Boolean getIsEnableCompletarTarea() {
        return isEnableCompletarTarea;
    }

    public void setIsEnableCompletarTarea(Boolean isEnableCompletarTarea) {
        this.isEnableCompletarTarea = isEnableCompletarTarea;
    }

    public java.util.Date getFechaAtencionTramite() {
        return fechaAtencionTramite;
    }

    public void setFechaAtencionTramite(java.util.Date fechaAtencionTramite) {
        this.fechaAtencionTramite = fechaAtencionTramite;
    }

    public CentroControlArmasController getCentroControlArmasController() {
        return centroControlArmasController;
    }

    public void setCentroControlArmasController(
            CentroControlArmasController centroControlArmasController) {
        this.centroControlArmasController = centroControlArmasController;
    }

    public Boolean getRequiereCustodiosBln() {
        return requiereCustodiosBln;
    }

    public void setRequiereCustodiosBln(Boolean requiereCustodiosBln) {
        this.requiereCustodiosBln = requiereCustodiosBln;
    }

    public void changeEstado() {
        System.out.println("EL ESTADO ACTUAL ES:" + estado);
    }

    public DocumentoHabilitanteController getDocumentoHabilitanteController() {
        return documentoHabilitanteController;
    }

    public void setDocumentoHabilitanteController(
            DocumentoHabilitanteController documentoHabilitanteController) {
        this.documentoHabilitanteController = documentoHabilitanteController;
    }

    public BigDecimal getCantidad() {
        return cantidad;
    }

    public void setCantidad(BigDecimal cantidad) {
        this.cantidad = cantidad;
    }

    public List<TarmSolicitudArmas> getArmas() {
        return armas;
    }

    public void setArmas(List<TarmSolicitudArmas> armas) {
        this.armas = armas;
    }

    public TarmSolicitudTramite getRecordSolicitudTra() {
        return recordSolicitudTra;
    }

    public void setRecordSolicitudTra(TarmSolicitudTramite recordSolicitudTra) {
        this.recordSolicitudTra = recordSolicitudTra;
    }

    public AgenciaArmaController getAgenciaArma() {
        return agenciaArma;
    }

    public void setAgenciaArma(AgenciaArmaController agenciaArma) {
        this.agenciaArma = agenciaArma;
    }

    public CargaController getCargaController() {
        return cargaController;
    }

    public void setCargaController(CargaController cargaController) {
        this.cargaController = cargaController;
    }

    public Boolean getRequiereNoSolAucpBln() {
        return requiereNoSolAucpBln;
    }

    public void setRequiereNoSolAucpBln(Boolean requiereNoSolAucpBln) {
        this.requiereNoSolAucpBln = requiereNoSolAucpBln;
    }

    public String getNombreInstitucion() {
        return nombreInstitucion;
    }

    public String setNombreInstitucion(String nombreInstitucion) {
        if (nombreInstitucion != null && !nombreInstitucion.isEmpty()) {
            this.nombreInstitucion = nombreInstitucion;
        } else {
            this.nombreInstitucion = "";
        }

        return nombreInstitucion;
    }

}
