/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arrebol.taxiservicios.controller.payroll;

import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.payroll.Adelantos;
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.Path;
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 Oscar
 */
public class AdelantosController extends ConnectionManager implements Serializable {
 
    public List<Adelantos> findAdelantosBetweenDates(Date startDate, Date endDate, String idLocation) {
        logger.info("findAdelantosBetweenDates");
        List<Adelantos> results = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<Adelantos> query = builder.createQuery(Adelantos.class);
            Root<Adelantos> root = query.from(Adelantos.class);

            Path<String> id = root.get("id");
            Path<Person> employee = root.get("employee");
            Path<Double> amount = root.get("amount");
            Path<String> comment = root.get("comment");
            Path<Date> createdOn = root.get("createdOn");
            Path<User> createdByPath = root.get("createdBy");
            Path<Location> locationPath = root.get("location");

            Predicate activeStatusPredicate = builder.equal(root.get("active"), Boolean.TRUE);
            Predicate startDatePredicate = builder.greaterThanOrEqualTo(root.get("createdOn"), startDate);
            Predicate endDatePredicate = builder.lessThanOrEqualTo(root.get("createdOn"), endDate);
            Predicate locationPredicate = builder.equal(root.get("location"), new Location(idLocation));

            query.select(
                    builder.construct(
                            Adelantos.class,
                            id, employee, amount,
                            comment, createdOn, createdByPath, locationPath
                    )
            );
            query.where(builder.and(activeStatusPredicate, startDatePredicate, endDatePredicate, locationPredicate));
            query.orderBy(builder.asc(root.get("createdOn")));

            results = session.createQuery(query).getResultList();

            transaction.commit();

            logger.info("Adelantos list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find Adelantos between dates", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findAdelantosBetweenDates()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public boolean save(Adelantos adelantos) {
        logger.info("save");

        boolean success = false;
        Transaction transaction = null;

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

            session.save(adelantos);

            transaction.commit();
            success = true;
        } catch (HibernateException e) {
            logger.error("Can not save adelanto", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method save()", e);
            rollback(transaction);
        }
        return success;
    }
    
    public User findUserById(String id) {
        User result = null;
        Transaction transaction = null;

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

            result = session.find(User.class, id);

            transaction.commit();
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Can not found user by id", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method findUserById", e);
        }

        return result;
    }
    
    public List<User> fillUserByLocation(Location location) {
        logger.info("fillUserByLocation");

        List<User> results = null;
        Transaction transaction = null;

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

            results = session.createQuery("FROM User WHERE location.id = :location ORDER BY createdOn DESC")
                    .setParameter("location", location.getId())
                    .getResultList();

            transaction.commit();
            logger.info("Total of user founds in auto complete search " + results.size());
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Can not load auto complete list of user", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillUserByLocation", e);
        }

        return results;
    }
    
    private static final long serialVersionUID = -3049612223190797349L;
    final Logger logger = LogManager.getLogger(AdelantosController.class);
}
