/*
 * 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.spa;

import com.arrebol.taxiservicios.controller.admin.GenericPersonController;
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.EstatusSolicitud;
import com.arrebol.taxiservicios.model.enums.GenericEnumType;
import com.arrebol.taxiservicios.model.spa.DevolucionPagoVenta;
import com.arrebol.taxiservicios.model.spa.SolicitudDevolucionPagoVenta;
import com.arrebol.taxiservicios.model.spa.SolicitudesCancelacionVenta;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
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 Crov
 */
public class DevolucionesController extends GenericPersonController implements Serializable {

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

   public boolean addSolicitudDevolucionPagoVenta(SolicitudDevolucionPagoVenta modelo, User user, boolean save) {
      logger.info("addSolicitudDevolucionPagoVenta");
      boolean success = false;
      Transaction transaction = null;

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

         if (save) {
            modelo.setId(UUID.randomUUID().toString());
            modelo.setCreatedBy(user);
            modelo.setCreatedOn(correcciónDeHr(new Date(), -7));
            session.save(modelo);
            transaction.commit();
            logger.info("Solicitud saved " + modelo.getId());
         } else {
            modelo.setLastUpdatedOn(correcciónDeHr(new Date(), -7));
            modelo.setLastUpdatedBy(user);
            session.update(modelo);
            transaction.commit();
            logger.info("Solicitud updated " + modelo.getId());
         }

         success = true;
      } catch (HibernateException e) {
         logger.error("Solicitud can not be added ", e);
         rollback(transaction);
      } catch (Exception e) {
         logger.error("Method addSolicitudDevolucionPagoVenta() ", e);
         rollback(transaction);
      }
      return success;
   }

   public boolean addSolicitudDevolucionVenta(SolicitudesCancelacionVenta modelo, User user, boolean save) {
      logger.info("addSolicitudDevolucionVenta");
      boolean success = false;
      Transaction transaction = null;

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

         if (save) {
            modelo.setId(UUID.randomUUID().toString());
            modelo.setCreatedBy(user);
            modelo.setCreatedOn(correcciónDeHr(new Date(), -7));
            session.save(modelo);
            transaction.commit();
            logger.info("Solicitud saved " + modelo.getId());
         } else {
            modelo.setLastUpdatedOn(correcciónDeHr(new Date(), -7));
            modelo.setLastUpdatedBy(user);
            session.update(modelo);
            transaction.commit();
            logger.info("Solicitud updated " + modelo.getId());
         }

         success = true;
      } catch (HibernateException e) {
         logger.error("Solicitud can not be added ", e);
         rollback(transaction);
      } catch (Exception e) {
         logger.error("Method addSolicitudDevolucionVenta() ", e);
         rollback(transaction);
      }
      return success;
   }

   public boolean addDevolucionPagoVenta(DevolucionPagoVenta modelo, User user, boolean save) {
      logger.info("addDevolucionPagoVenta");
      boolean success = false;
      Transaction transaction = null;

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

         if (save) {
            modelo.setId(UUID.randomUUID().toString());
            modelo.setCreatedBy(user);
            modelo.setCreatedOn(correcciónDeHr(new Date(), -7));
            session.save(modelo);
            transaction.commit();
            logger.info("Devolucion saved " + modelo.getId());
         } else {
            modelo.setLastUpdatedOn(correcciónDeHr(new Date(), -7));
            modelo.setLastUpdatedBy(user);
            session.update(modelo);
            transaction.commit();
            logger.info("Devolucion updated " + modelo.getId());
         }

         success = true;
      } catch (HibernateException e) {
         logger.error("Devolucion can not be added ", e);
         rollback(transaction);
      } catch (Exception e) {
         logger.error("Method addDevolucionPagoVenta() ", e);
         rollback(transaction);
      }
      return success;
   }

   public long countSolicitudesPagoDevolusion(String idVenta) {
      logger.info("countSolicitudesPagoDevolusion()");
      long count = 0;
      Transaction transaction = null;
      try {
         Session session = HibernateUtil.getSessionFactory().getCurrentSession();
         transaction = session.beginTransaction();
         CriteriaBuilder builder = session.getCriteriaBuilder();
         CriteriaQuery<Long> criteria = builder.createQuery(Long.class);
         Root<SolicitudDevolucionPagoVenta> root = criteria.from(SolicitudDevolucionPagoVenta.class);
         criteria.select(builder.count(root));
         criteria.where(
                 builder.equal(root.get("venta").get("id"), idVenta),
                 builder.equal(root.get("estatusActivo"), GenericEnumType.ENABLED),
                 builder.equal(root.get("estatusSolicitud"), EstatusSolicitud.PENDIENTE)
         );
         count = session.createQuery(criteria).getSingleResult();
         logger.info("Total of solicitudes found: " + count);
         transaction.commit();
      } catch (HibernateException e) {
         rollback(transaction);
         logger.error("Unable to count solicitudes", e);
      } catch (Exception e) {
         rollback(transaction);
         logger.error("Method countSolicitudesPagoDevolusion", e);
      }
      return count;
   }

   public List<SolicitudDevolucionPagoVenta> fillSolicitudDevolucionPagoVentaByLocation(Location location) {
      logger.info("fillSolicitudDevolucionPagoVentaByLocation");
      List<SolicitudDevolucionPagoVenta> resultList = null;
      Transaction transaction = null;
      try {
         logger.info("Searching for solicitudes..");
         Session session = HibernateUtil.getSessionFactory().getCurrentSession();
         transaction = session.beginTransaction();
         CriteriaBuilder builder = session.getCriteriaBuilder();

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

         Predicate criterio = (builder.equal(root.get("location"), location));
         Predicate criterio2 = (builder.equal(root.get("estatusActivo"), GenericEnumType.ENABLED));
         criteria.where(builder.and(criterio, criterio2));
         criteria.orderBy(builder.asc(root.get("createdOn")));
         resultList = session.createQuery(criteria).getResultList();

         logger.info("Total off solicitudes found: " + (null == resultList ? -1 : resultList.size()));
         transaction.commit();
      } catch (HibernateException e) {
         logger.error("Solicitudes cannot be loaded" + e);
         rollback(transaction);
      } catch (Exception e) {
         logger.error("Method fillSolicitudDevolucionPagoVentaByLocation(): " + e);
         rollback(transaction);
      }
      return resultList;
   }

   public List<SolicitudesCancelacionVenta> fillSolicitudesCancelacionVentaByLocation(Location location) {
      logger.info("fillSolicitudesCancelacionVentaByLocation");
      List<SolicitudesCancelacionVenta> resultList = null;
      Transaction transaction = null;
      try {
         logger.info("Searching for solicitudes..");
         Session session = HibernateUtil.getSessionFactory().getCurrentSession();
         transaction = session.beginTransaction();
         CriteriaBuilder builder = session.getCriteriaBuilder();

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

         Predicate criterio = (builder.equal(root.get("venta").get("location"), location));
         Predicate criterio2 = (builder.equal(root.get("estatusActivo"), GenericEnumType.ENABLED));
         criteria.where(builder.and(criterio, criterio2));
         criteria.orderBy(builder.asc(root.get("createdOn")));
         resultList = session.createQuery(criteria).getResultList();

         logger.info("Total off solicitudes found: " + (null == resultList ? -1 : resultList.size()));
         transaction.commit();
      } catch (HibernateException e) {
         logger.error("Solicitudes cannot be loaded" + e);
         rollback(transaction);
      } catch (Exception e) {
         logger.error("Method fillSolicitudesCancelacionVentaByLocation(): " + e);
         rollback(transaction);
      }
      return resultList;
   }

   private Date correcciónDeHr(Date fecha, int horas) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(fecha);
      calendar.add(Calendar.HOUR_OF_DAY, horas);
      Date nuevaFecha = calendar.getTime();
      return nuevaFecha;
   }
}
