/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
 */
package com.arrebol.taxiservicios.controller.admin;

import com.arrebol.taxiservicios.controller.predio.PredioController;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.enums.EstatusRembolso;
import com.arrebol.taxiservicios.model.enums.EstatusSolicitud;
import com.arrebol.taxiservicios.model.enums.GenericEnumType;
import com.arrebol.taxiservicios.model.predio.AbonoLote;
import com.arrebol.taxiservicios.model.predio.AbonosRembolsoCancelacionCompraLote;
import com.arrebol.taxiservicios.model.predio.Lote;
import com.arrebol.taxiservicios.model.predio.RembolsosCancelacionCompraLote;
import com.arrebol.taxiservicios.model.predio.SolicitudesCancelacionCompraLote;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author pc one
 */
public class AprobarCancelacionController extends GenericPersonController implements Serializable {

    private static final long serialVersionUID = -6265444716269535946L;
    final Logger logger = LogManager.getLogger(PredioController.class);

    public boolean addSolcitud(SolicitudesCancelacionCompraLote solicitud, User user, boolean save) {
        logger.info("addSolcitud");
        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            if (save) {
                solicitud.setCreatedBy(user);
                solicitud.setCreatedOn(new Date());
                session.save(solicitud);
                transaction.commit();
                logger.info("Solicitud saved " + solicitud.getId());
            } else {
                solicitud.setLastUpdatedBy(user);
                solicitud.setLastUpdatedOn(new Date());
                session.update(solicitud);
                transaction.commit();
                logger.info("Solicitud updated " + solicitud.getId());
            }
            success = true;
        } catch (HibernateException e) {
            logger.error("Solicitud can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addSolcitud() ", e);
            rollback(transaction);
        }
        return success;
    }

    public List<SolicitudesCancelacionCompraLote> fillAllSolicitudesByLocation(Location location) {
        logger.info("Searching all solicitudes..");

        List<SolicitudesCancelacionCompraLote> result = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<SolicitudesCancelacionCompraLote> criteria = builder.createQuery(SolicitudesCancelacionCompraLote.class);
            Root<SolicitudesCancelacionCompraLote> root = criteria.from(SolicitudesCancelacionCompraLote.class);

            Predicate criterioActivo = builder.equal(root.get("estatusActivo"), GenericEnumType.ENABLED);
            Predicate criterioPredioLocation = builder.equal(root.get("lote").get("manzana").get("predio").get("location"), location);
            criteria.where(builder.and(criterioActivo, criterioPredioLocation));

            criteria.orderBy(builder.desc(root.get("createdOn")));
            result = session.createQuery(criteria).getResultList();

            logger.info("Total of solicitudes found: " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Unable to load solicitudes list ", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillAllSolicitudesByEstatus", e);
        }

        return result;
    }
    
      public List<SolicitudesCancelacionCompraLote> fillAllSolicitudesByLoteAndEstatus(Lote lote,EstatusSolicitud estatus) {
        logger.info("Searching all solicitudes..");

        List<SolicitudesCancelacionCompraLote> result = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<SolicitudesCancelacionCompraLote> criteria = builder.createQuery(SolicitudesCancelacionCompraLote.class);
            Root<SolicitudesCancelacionCompraLote> root = criteria.from(SolicitudesCancelacionCompraLote.class);

            Predicate criterioActivo = builder.equal(root.get("estatusActivo"), GenericEnumType.ENABLED);
            Predicate criterioEstatus = builder.equal(root.get("estatusSolicitud"), estatus);
            Predicate criterioLote = builder.equal(root.get("lote").get("id"), lote.getId());
            criteria.where(builder.and(criterioActivo, criterioLote, criterioEstatus));

            criteria.orderBy(builder.desc(root.get("createdOn")));
            result = session.createQuery(criteria).getResultList();

            logger.info("Total of solicitudes found: " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Unable to load solicitudes list ", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillAllSolicitudesByEstatus", e);
        }

        return result;
    }

    public boolean addRembolso(RembolsosCancelacionCompraLote rembolso, User user, boolean save) {
        logger.info("addSolcitud");
        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            if (save) {
                rembolso.setCreatedBy(user);
                rembolso.setCreatedOn(new Date());
                session.save(rembolso);
                transaction.commit();
                logger.info("Rembolso saved " + rembolso.getId());
            } else {
                rembolso.setLastUpdatedBy(user);
                rembolso.setLastUpdatedOn(new Date());
                session.update(rembolso);
                transaction.commit();
                logger.info("Rembolso updated " + rembolso.getId());
            }
            success = true;
        } catch (HibernateException e) {
            logger.error("Rembolso can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addRembolso() ", e);
            rollback(transaction);
        }
        return success;
    }

    public List<RembolsosCancelacionCompraLote> fillAllRembolsosByLocation(Location location) {
        logger.info("Searching all rembolsos..");

        List<RembolsosCancelacionCompraLote> result = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<RembolsosCancelacionCompraLote> criteria = builder.createQuery(RembolsosCancelacionCompraLote.class);
            Root<RembolsosCancelacionCompraLote> root = criteria.from(RembolsosCancelacionCompraLote.class);

            Predicate criterioActivo = builder.equal(root.get("estatusActivo"), GenericEnumType.ENABLED);
            Predicate criterioPredioLocation = builder.equal(root.get("lote").get("manzana").get("predio").get("location"), location);
            criteria.where(builder.and(criterioActivo, criterioPredioLocation));

            criteria.orderBy(builder.desc(root.get("createdOn")));
            result = session.createQuery(criteria).getResultList();

            logger.info("Total of rembolsos found: " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Unable to load rembolsos list ", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillAllRembolsosByEstatus", e);
        }

        return result;
    }
    public RembolsosCancelacionCompraLote fillRembolsoBySolicitud(SolicitudesCancelacionCompraLote solicitud) {
        logger.info("Searching rembolso..");

        RembolsosCancelacionCompraLote result = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<RembolsosCancelacionCompraLote> criteria = builder.createQuery(RembolsosCancelacionCompraLote.class);
            Root<RembolsosCancelacionCompraLote> root = criteria.from(RembolsosCancelacionCompraLote.class);

            Predicate criterioSolicitud= builder.equal(root.get("solicitud").get("id"), solicitud.getId());
            Predicate criterioActivo = builder.equal(root.get("estatusActivo"), GenericEnumType.ENABLED);
            Predicate criterioActivoR = builder.equal(root.get("estatusRembolso"), EstatusRembolso.ESPERA);
            criteria.where(builder.and(criterioSolicitud, criterioActivo, criterioActivoR));
            result = session.createQuery(criteria).getSingleResult();

            transaction.commit();
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Unable to load rembolsos ", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillAllRembolsosBySolicitud", e);
        }

        return result;
    }
    

    public List<AbonoLote> fillAbonoLoteByLoteAndPagoEstatus(Lote lote, GenericEnumType pagoEstatus) {
        List<AbonoLote> resultList = null;
        Transaction transaction = null;
        try {
            logger.info("Searching for Lote.." + lote.getId());
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<AbonoLote> criteria = builder.createQuery(AbonoLote.class);
            Root<AbonoLote> root = criteria.from(AbonoLote.class);

            Predicate criterio = (builder.equal(root.get("lote"), lote));
            Predicate criterio2 = (builder.equal(root.get("estatusActivo"), GenericEnumType.ENABLED));
            Predicate criterio3 = (builder.equal(root.get("pagoEstatus"), pagoEstatus));
            criteria.where(builder.and(criterio, criterio2, criterio3));
            criteria.orderBy(builder.asc(root.get("fechaAPagar")));

            resultList = session.createQuery(criteria).getResultList();

            logger.info("Total of abonos found: " + (null == resultList ? -1 : resultList.size()));
            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Abonos cannot be loaded " + e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillAbonoLoteByLote() " + e);
            rollback(transaction);
        }
        return resultList;
    }
    
     public boolean addAbonosRembolso(AbonosRembolsoCancelacionCompraLote abono, User user, boolean save) {
        logger.info("add Abonos Rembolso");
        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            if (save) {
                abono.setCreatedBy(user);
                abono.setCreatedOn(new Date());
                session.save(abono);
                transaction.commit();
                logger.info("Abono saved " + abono.getId());
            } else {
                abono.setLastUpdatedBy(user);
                //abono.setLastUpdatedOn(new Date());
                session.update(abono);
                transaction.commit();
                logger.info("Abono updated " + abono.getId());
            }
            success = true;
        } catch (HibernateException e) {
            logger.error("Abono can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addAbonosRembolso() ", e);
            rollback(transaction);
        }
        return success;
    }
     
     public List<AbonosRembolsoCancelacionCompraLote> fillAllAbonosByRembolso(RembolsosCancelacionCompraLote rembolso) {
        logger.info("Searching all rembolsos..");

        List<AbonosRembolsoCancelacionCompraLote> result = null;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaQuery<AbonosRembolsoCancelacionCompraLote> criteria = builder.createQuery(AbonosRembolsoCancelacionCompraLote.class);
            Root<AbonosRembolsoCancelacionCompraLote> root = criteria.from(AbonosRembolsoCancelacionCompraLote.class);

            Predicate criterioActivo = builder.equal(root.get("estatusActivo"), GenericEnumType.ENABLED);
            Predicate escriterioRembolso = builder.equal(root.get("rembolso").get("id"), rembolso.getId());
            criteria.where(builder.and(criterioActivo, escriterioRembolso));

            criteria.orderBy(builder.asc(root.get("consecutivo")));
            result = session.createQuery(criteria).getResultList();

            logger.info("Total of rembolsos found: " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Unable to load rembolsos list ", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillAllAbonosByRembolso", e);
        }

        return result;
    }

}
