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

import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.admin.EmployeeSanction;
import com.arrebol.taxiservicios.model.admin.Sanction;
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.enums.EmployeeSanctionType;
import com.arrebol.taxiservicios.model.enums.ExpenseStatusType;
import com.arrebol.taxiservicios.model.enums.PersonType;
import com.arrebol.taxiservicios.model.enums.SanctionType;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.criteria.Expression;
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 oscarvargas
 */
public class SanctionController extends ConnectionManager implements Serializable{
    
    public List<Sanction> fillSanctionDataTableBetweenDates(Date starDate, Date endDate, Location location) {
        logger.info("fillExpenseDataTableBetweenDates");

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

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

            results = session.createQuery("SELECT exp FROM Sanction exp "
                    + "WHERE exp.type NOT IN ('FEE') AND "
                    + "(DATE(exp.createdOn) BETWEEN DATE(:starDate) AND DATE(:endDate)) AND "
                    + "exp.location.id = :location ORDER BY exp.createdOn DESC")
                    .setParameter("starDate", starDate)
                    .setParameter("endDate", endDate)
                    .setParameter("location", location.getId())
                    .getResultList();

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

        return results;
    }
    
    public List<Sanction> fillSanctionDataTableBetweenDatesIngresos(Date starDate, Date endDate, String location) {
        logger.info("fillExpenseDataTableBetweenDatesIngresos");

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

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

            
            CriteriaBuilder builder = session.getCriteriaBuilder();
            
            CriteriaQuery<Sanction> query = builder.createQuery(Sanction.class);
            Root<Sanction> root = query.from(Sanction.class);

            
            List<SanctionType> parentList = Arrays.asList(new SanctionType[]{SanctionType.ADD, SanctionType.FEE,SanctionType.ESTUDIO,SanctionType.INGRESO_SINIESTRO,SanctionType.ABONO_DEUDA,SanctionType.INGRESO_PAGO_LAMINADO});
            
            Expression<SanctionType> parentExpression = root.get("type");
            Predicate parentPredicate = parentExpression.in(parentList);
            
            Predicate startDatePredicate = builder.greaterThanOrEqualTo(root.get("createdOn"), starDate);
            Predicate endDatePredicate = builder.lessThanOrEqualTo(root.get("createdOn"), endDate);
            Predicate locationPredicate = builder.equal(root.get("location").get("id"), location);
            
             query.where(builder.and(
                    parentPredicate, startDatePredicate, endDatePredicate, locationPredicate
            ));
            query.orderBy(builder.asc(root.get("createdOn")));

            results = session.createQuery(query).getResultList();
            transaction.commit();
            logger.info("Total of Sanction founds in auto complete search " + results.size());
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Can not load auto complete list of Sanction", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillExpenseDataTableBetweenDates", e);
        }

        return results;
    }
    
     public List<Sanction> fillSanctionDataTableBetweenDatesEgresos(Date starDate, Date endDate, String location) {
        logger.info("fillExpenseDataTableBetweenDatesEgresos");

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

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

            
            CriteriaBuilder builder = session.getCriteriaBuilder();
            
            CriteriaQuery<Sanction> query = builder.createQuery(Sanction.class);
            Root<Sanction> root = query.from(Sanction.class);

            
            List<SanctionType> parentList = Arrays.asList(new SanctionType[]{SanctionType.SANCTION, SanctionType.DISPOSITION,SanctionType.ACCIDENT,SanctionType.RETORNO_EFECTIVO,SanctionType.DISPOSICION_INGRESO,SanctionType.DISPOSICION_FINIQUITO,SanctionType.AGREGAR_DEUDA});
            
            Expression<SanctionType> parentExpression = root.get("type");
            Predicate parentPredicate = parentExpression.in(parentList);
            
            Predicate startDatePredicate = builder.greaterThanOrEqualTo(root.get("createdOn"), starDate);
            Predicate endDatePredicate = builder.lessThanOrEqualTo(root.get("createdOn"), endDate);
            Predicate locationPredicate = builder.equal(root.get("location").get("id"), location);
            
             query.where(builder.and(
                    parentPredicate, startDatePredicate, endDatePredicate, locationPredicate
            ));
            query.orderBy(builder.asc(root.get("createdOn")));

            results = session.createQuery(query).getResultList();
            transaction.commit();
            logger.info("Total of Sanction founds in auto complete search " + results.size());
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Can not load auto complete list of Sanction", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillExpenseDataTableBetweenDates", e);
        }

        return results;
    }
    
   
    
    public List<Sanction> fillSanctionDataTablePending(Location location) {
        logger.info("fillSanctionDataTablePending");

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

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

            results = session.createQuery("SELECT exp FROM Sanction exp "
                    + "WHERE exp.type NOT IN ('FEE') AND exp.depositStatus='PENDING' AND "
                    + "exp.location.id = :location ORDER BY exp.createdOn DESC")
                  
                    .setParameter("location", location.getId())
                    .getResultList();

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

        return results;
    }
    
    public List<Sanction> fillSanctionFeeDataTableBetweenDates(Date starDate, Date endDate, Location location) {
        logger.info("fillSanctionFeeDataTableBetweenDates");

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

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

            results = session.createQuery("SELECT exp FROM Sanction exp "
                    + "WHERE exp.type IN ('FEE', 'FEE_TRANSFER') AND "
                    + "(DATE(exp.createdOn) BETWEEN DATE(:starDate) AND DATE(:endDate)) AND "
                    + "exp.location.id = :location ORDER BY exp.createdOn DESC")
                    .setParameter("starDate", starDate)
                    .setParameter("endDate", endDate)
                    .setParameter("location", location.getId())
                    .getResultList();

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

        return results;
    }
    
    public List<Sanction> fillSanctionDatatable() {

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

        try {
            logger.info("Searching all sanctions..");
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

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

            Path<String> idPath = root.get("id");
            Path<String> paymentPath = root.get("payment");
            Path<String> paymentDatePath = root.get("paymentDate");
            Path<String> descriptionPath = root.get("description");
            Path<String> typePath = root.get("type");
            Path<String> driverPath = root.get("driver");
            Path<User> createdByPath = root.get("createdBy");
            
            Predicate feePredicate = builder.notEqual(root.get("type"), SanctionType.FEE);

            criteria.select(
                    builder.construct(Sanction.class, idPath, paymentPath, paymentDatePath,
                            descriptionPath, typePath, driverPath, createdByPath
                    ));
            criteria.where(builder.and(feePredicate));
            criteria.orderBy(
                    builder.asc(root.get("createdOn"))
            );

            result = session.createQuery(criteria).getResultList();
            transaction.commit();
            logger.info("Total of sanctions found for datatable: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            logger.error("Can not load list of sanctios for datatable ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillSanctionDatatable of Sanctions", e);
            rollback(transaction);
        }

        return result;
    }
    
    public List<Sanction> fillSanctionDatatableByDriver(String id) {

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

        try {
            logger.info("Searching all sanctions..");
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

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

            Path<String> idPath = root.get("id");
            Path<String> paymentPath = root.get("payment");
            Path<String> paymentDatePath = root.get("paymentDate");
            Path<String> descriptionPath = root.get("description");
            Path<String> typePath = root.get("type");
            Path<String> driverPath = root.get("driver");
            Path<User> createdByPath = root.get("createdBy");
            
            Predicate feePredicate = builder.notEqual(root.get("type"), SanctionType.FEE);
            Predicate idDriverPredicate = builder.equal(root.get("driver"), new Person(id));

            criteria.select(
                    builder.construct(Sanction.class, idPath, paymentPath, paymentDatePath,
                            descriptionPath, typePath, driverPath, createdByPath
                    ));
            criteria.where(builder.and(feePredicate, idDriverPredicate));
            criteria.orderBy(
                    builder.asc(root.get("createdOn"))
            );

            result = session.createQuery(criteria).getResultList();
            transaction.commit();
            logger.info("Total of sanctions found for datatable: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            logger.error("Can not load list of sanctios for datatable ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillSanctionDatatable of Sanctions", e);
            rollback(transaction);
        }

        return result;
    }
    
    public List<Sanction> fillSanctionFeeDatatable() {

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

        try {
            logger.info("Searching all sanctions..");
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

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

            Path<String> idPath = root.get("id");
            Path<String> paymentPath = root.get("payment");
            Path<String> paymentDatePath = root.get("paymentDate");
            Path<String> descriptionPath = root.get("description");
            Path<String> typePath = root.get("type");
            Path<String> driverPath = root.get("driver");
            
            List<SanctionType> status = new ArrayList<SanctionType>();
            status.add(SanctionType.FEE);
            status.add(SanctionType.FEE_TRANSFER);
            
            Expression<SanctionType> expression = root.get("type");
            Predicate inClause = expression.in(status);

            criteria.select(
                    builder.construct(Sanction.class, idPath, paymentPath, paymentDatePath, 
                            descriptionPath, typePath, driverPath
                    ));
            criteria.where(builder.and(inClause));
            criteria.orderBy(
                    builder.asc(root.get("createdOn"))
            );

            result = session.createQuery(criteria).getResultList();
            transaction.commit();
            logger.info("Total of sanctions found for datatable: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            logger.error("Can not load list of sanctios for datatable ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillSanctionDatatable of Sanctions", e);
            rollback(transaction);
        }

        return result;
    }
    
    public List<Person> fillDriversComboBox() {

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

        try {
            logger.info("Searching all drivers to select..");
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

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

            Path<String> idPath = root.get("id");
            Path<String> firstNamePath = root.get("firstName");
            Path<String> secondNamePath = root.get("secondName");
            Path<String> lastNamePath = root.get("lastName");
            Path<String> middleNamePath = root.get("middleName");

            criteria.select(
                    builder.construct(Person.class, idPath, firstNamePath, secondNamePath, lastNamePath, middleNamePath
                    ));

            criteria.where(builder.equal(root.get("personType"), PersonType.DRIVER));
            
            criteria.orderBy(
                    builder.asc(root.get("firstName")),
                    builder.asc(root.get("secondName")),
                    builder.asc(root.get("lastName")),
                    builder.asc(root.get("middleName"))
            );

            result = session.createQuery(criteria).getResultList();
            transaction.commit();
            logger.info("Total of drivers found for datatable: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            logger.error("Can not load list of drivers for datatable ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillDriversComboBox of Sanction", e);
            rollback(transaction);
        }

        return result;
    }
    
    public boolean autorizar(String sanctionId) {
        logger.info("autorizar");

        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaUpdate<Sanction> update = builder.createCriteriaUpdate(Sanction.class);
            Root<Sanction> rootUpdate = update.from(Sanction.class);

            update.set("status", ExpenseStatusType.AUTHORIZED);
            update.where(builder.equal(rootUpdate.get("id"), sanctionId));

            int total = session.createQuery(update).executeUpdate();

            if (1 == total) {
                transaction.commit();
                success = true;
                logger.info("Sanction " + sanctionId + " updated");
            } else {
                transaction.rollback();
                logger.error("Error Sale updated total: " + total);
            }
        } catch (HibernateException e) {
            logger.error("Sanction can not be updated ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method autorizar() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    public boolean updateTicketStatus(String sanctionId,  String userId) {
        logger.info("autorizar");

        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaUpdate<Sanction> update = builder.createCriteriaUpdate(Sanction.class);
            Root<Sanction> rootUpdate = update.from(Sanction.class);

            update.set("active", true);
            update.set("lastUpdatedBy", new User(userId, true));
            update.set("lastUpdatedOn", new Date());
            update.where(builder.equal(rootUpdate.get("id"), sanctionId));
            
            int total = session.createQuery(update).executeUpdate();
            if (1 == total) {
                transaction.commit();
                success = true;
                logger.info("sanction " + sanctionId + " the status was updated by ticket printing");
            } else {
                transaction.rollback();
                logger.error("Error sanction updated total: " + total + " by ticket printing");
            }
        } catch (HibernateException e) {
            logger.error("Sanction can not be updated ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method updateTicketStatus() ", e);
            rollback(transaction);
        }
        return success;
    }

    public boolean autorizarDeposit(String sanctionId) {
        logger.info("autorizar");

        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaUpdate<Sanction> update = builder.createCriteriaUpdate(Sanction.class);
            Root<Sanction> rootUpdate = update.from(Sanction.class);

            update.set("depositStatus", ExpenseStatusType.AUTHORIZED);
            update.where(builder.equal(rootUpdate.get("id"), sanctionId));

            int total = session.createQuery(update).executeUpdate();

            if (1 == total) {
                transaction.commit();
                success = true;
                logger.info("Sanction " + sanctionId + " updated");
            } else {
                transaction.rollback();
                logger.error("Error Sale updated total: " + total);
            }
        } catch (HibernateException e) {
            logger.error("Sanction can not be updated ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method autorizar() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    public boolean addSanction(Sanction sanction, String userName, String driverId) {
        logger.info("addSanction");
        boolean success = false;

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

            sanction.setCreatedBy(new User(userName, ""));
            sanction.setDriver(new Person(driverId));
            sanction.setActive(false);
            session.save(sanction);
            logger.info("sanction saved " + sanction.getId());

            transaction.commit();

            success = true;
        } catch (HibernateException e) {
            logger.error("Sanction can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addSanction() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    public boolean addEmployeeSanction(EmployeeSanction sanction, String userName, String driverId) {
        logger.info("addEmployeeSanction");
        boolean success = false;

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

            sanction.setCreatedBy(new User(userName, ""));
            sanction.setEmployee(new Person(driverId));
            sanction.setActive(true);
            session.save(sanction);
            logger.info("employee sanction saved " + sanction.getId());

            transaction.commit();

            success = true;
        } catch (HibernateException e) {
            logger.error("employee sanction can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method addEmployeeSanction() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    public boolean deleteSanctionById(String sanctionId) {
        logger.info("deleteSanctionById");

        boolean success = false;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            CriteriaBuilder builder = session.getCriteriaBuilder();

            builder = session.getCriteriaBuilder();
            CriteriaDelete<Sanction> delete = builder.createCriteriaDelete(Sanction.class);
            Root<Sanction> root = delete.from(Sanction.class);

                delete.where(builder.equal(root.get("id"), sanctionId));

                int total = session.createQuery(delete).executeUpdate();

            if (1 == total) {
                transaction.commit();
                success = true;
                logger.info("Sanction " + sanctionId + " deleted");
            } else {
                transaction.rollback();
                logger.error("Error Sanction deleted total: " + total);
            }
        } catch (HibernateException e) {
            logger.error("Sanction can not be deleted ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method deleteSanctionById() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    public Sanction getSanctionById(String sanctionId) {
        logger.info("getPersonById");

        Sanction sanction = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();

            sanction = session.get(Sanction.class, sanctionId);

            transaction.commit();
            logger.info("Sanction " + sanction);
        } catch (HibernateException e) {
            logger.error("Sanction cannot be loaded " + sanctionId, e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method getSanctionById(" + sanctionId + ") ", e);
            rollback(transaction);
        }
        return sanction;
    }
    
    public List<Sanction> fillSanctionDatatableByDriverFinancing(String id) {

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

        try {
            logger.info("Searching all sanctions..");
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

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

            Path<String> idPath = root.get("id");
            Path<String> paymentPath = root.get("payment");
            Path<String> paymentDatePath = root.get("paymentDate");
            Path<String> descriptionPath = root.get("description");
            Path<String> typePath = root.get("type");
            Path<String> driverPath = root.get("driver");
            Path<User> createdByPath = root.get("createdBy");
            
            Predicate abonoPredicate = builder.equal(root.get("type"), SanctionType.ABONO_DEUDA);
            Predicate deudaPredicate = builder.equal(root.get("type"), SanctionType.AGREGAR_DEUDA);
            Predicate idDriverPredicate = builder.equal(root.get("driver"), new Person(id));

            criteria.select(
                    builder.construct(Sanction.class, idPath, paymentPath, paymentDatePath,
                            descriptionPath, typePath, driverPath, createdByPath
                    ));
            criteria.where(builder.and(builder.or(abonoPredicate, deudaPredicate), idDriverPredicate));
            criteria.orderBy(
                    builder.asc(root.get("createdOn"))
            );

            result = session.createQuery(criteria).getResultList();
            transaction.commit();
            logger.info("Total of sanctions found for datatable: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            logger.error("Can not load list of sanctios for datatable ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillSanctionDatatable of Sanctions", e);
            rollback(transaction);
        }

        return result;
    }
    
    public List<Sanction> fillSanctionDatatableFinancing(Date starDate, Date endDate, Location location) {
        logger.info("fillSanctionDatatableFinancing");

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

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

            results = session.createQuery("SELECT exp FROM Sanction exp "
                    + "WHERE exp.type IN ('ABONO_DEUDA', 'AGREGAR_DEUDA') AND "
                    + "(DATE(exp.createdOn) BETWEEN DATE(:starDate) AND DATE(:endDate)) AND "
                    + "exp.location.id = :location ORDER BY exp.createdOn DESC")
                    .setParameter("starDate", starDate)
                    .setParameter("endDate", endDate)
                    .setParameter("location", location.getId())
                    .getResultList();

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

        return results;
    }
    
    public List<EmployeeSanction> fillEmployeeSanctionDatatableByEmployeeFinancing(String id) {

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

        try {
            logger.info("Searching all employee sanctions..");
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

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

            Path<String> idPath = root.get("id");
            Path<String> paymentPath = root.get("payment");
            Path<String> descriptionPath = root.get("description");
            Path<String> typePath = root.get("type");
            Path<String> driverPath = root.get("employee");
            Path<User> createdByPath = root.get("createdBy");
            Path<String> createdPath = root.get("createdOn");
            Path<String> paymentWeek = root.get("paymentWeek");
            Path<String> amountToPay = root.get("amountToPay");
            
            Predicate abonoPredicate = builder.equal(root.get("type"), EmployeeSanctionType.ABONO_DEUDA);
            Predicate abonoNominaPredicate = builder.equal(root.get("type"), EmployeeSanctionType.ABONO_DEUDA_NOMINA);
            Predicate deudaPredicate = builder.equal(root.get("type"), EmployeeSanctionType.AGREGAR_DEUDA);
            Predicate idEmployeePredicate = builder.equal(root.get("employee"), new Person(id));

            criteria.select(
                    builder.construct(EmployeeSanction.class, idPath, paymentPath,
                            descriptionPath, typePath, driverPath, createdByPath, createdPath, paymentWeek, amountToPay
                    ));
            criteria.where(builder.and(builder.or(abonoPredicate, abonoNominaPredicate, deudaPredicate), idEmployeePredicate));
            criteria.orderBy(
                    builder.asc(root.get("createdOn"))
            );

            result = session.createQuery(criteria).getResultList();
            transaction.commit();
            logger.info("Total of employee sanctions found for datatable: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            logger.error("Can not load list of employee sanctios for datatable ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillEmployeeSanctionDatatableByEmployeeFinancing of Employee Sanctions", e);
            rollback(transaction);
        }

        return result;
    }
    
    public List<EmployeeSanction> fillEmployeeSanctionDatatableByEmployeeFinancing(Date starDate, Date endDate, Location location) {
        logger.info("fillEmployeeSanctionDatatableByEmployeeFinancing");

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

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

            results = session.createQuery("SELECT exp FROM EmployeeSanction exp "
                    + "WHERE exp.type IN ('ABONO_DEUDA', 'ABONO_DEUDA_NOMINA', 'AGREGAR_DEUDA') AND "
                    + "(DATE(exp.createdOn) BETWEEN DATE(:starDate) AND DATE(:endDate)) AND "
                    + "exp.location.id = :location ORDER BY exp.createdOn DESC")
                    .setParameter("starDate", starDate)
                    .setParameter("endDate", endDate)
                    .setParameter("location", location.getId())
                    .getResultList();

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

        return results;
    }
    
    public List<EmployeeSanction> fillEmployeeSanctionDatatableByEmployeeSaving(String id) {

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

        try {
            logger.info("Searching all employee sanctions..");
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();

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

            Path<String> idPath = root.get("id");
            Path<String> paymentPath = root.get("payment");
            Path<String> descriptionPath = root.get("description");
            Path<String> typePath = root.get("type");
            Path<String> driverPath = root.get("employee");
            Path<User> createdByPath = root.get("createdBy");
            Path<String> createdPath = root.get("createdOn");
            Path<String> paymentWeek = root.get("paymentWeek");
            Path<String> amountToPay = root.get("amountToPay");
            
            Predicate abonoPredicate = builder.equal(root.get("type"), EmployeeSanctionType.SAVING);
            Predicate abonoNominaPredicate = builder.equal(root.get("type"), EmployeeSanctionType.SAVING_NOMINA);
            Predicate deudaPredicate = builder.equal(root.get("type"), EmployeeSanctionType.DISPOSICION_AHORRO);
            Predicate idEmployeePredicate = builder.equal(root.get("employee"), new Person(id));

            criteria.select(
                    builder.construct(EmployeeSanction.class, idPath, paymentPath,
                            descriptionPath, typePath, driverPath, createdByPath, createdPath, paymentWeek, amountToPay
                    ));
            criteria.where(builder.and(builder.or(abonoPredicate, abonoNominaPredicate, deudaPredicate), idEmployeePredicate));
            criteria.orderBy(
                    builder.asc(root.get("createdOn"))
            );

            result = session.createQuery(criteria).getResultList();
            transaction.commit();
            logger.info("Total of employee sanctions found for datatable: " + (null == result ? -1 : result.size()));
        } catch (HibernateException e) {
            logger.error("Can not load list of employee sanctios for datatable ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillEmployeeSanctionDatatableByEmployeeSaving of Employee Sanctions", e);
            rollback(transaction);
        }

        return result;
    }
    
    private static final long serialVersionUID = 1020525241432403643L;
    
    final Logger logger = LogManager.getLogger(SanctionController.class);

    public SanctionController() {
    }
    
}
