/*
 * Arrebol Consultancy copyright.
 * 
 * This code belongs to Arrebol Consultancy
 * its use, redistribution or modification are prohibited 
 * without written authorization from Arrebol Consultancy.
 */
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.ClosingDay;
import com.arrebol.taxiservicios.model.admin.EmployeeSanction;
import com.arrebol.taxiservicios.model.admin.Expense;
import com.arrebol.taxiservicios.model.admin.ExpenseCompany;
import com.arrebol.taxiservicios.model.admin.Sale;
import com.arrebol.taxiservicios.model.admin.StableGeneralBox;
import com.arrebol.taxiservicios.model.admin.Taxes;
import com.arrebol.taxiservicios.model.admin.TransferMoneyLocation;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.arrebol.taxiservicios.model.payroll.Adelantos;
import com.arrebol.taxiservicios.model.payroll.Payroll;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
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;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;

/**
 *
 * @author Carlos Janitzio Zavala Lopez <janitzio.zavala@arrebol.com.mx>
 */
public class StableGeneralBoxController extends ConnectionManager implements Serializable {

    /**
     *
     * @param date
     * @return
     */
    public boolean existNextPaidStableGeneralBoxByCreatedOn(Date date, String locationId) {
        logger.info("existNextPaidStableGeneralBoxByCreatedOn");

        boolean success = true;
        Transaction transaction = null;

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

            String query = "SELECT sgb.id "
                    + "FROM stable_general_box sgb "
                    + "WHERE DATE(sgb.created_on) >= DATE_ADD(DATE(:date), INTERVAL 1 DAY) "
                    + "AND sgb.active_status = 'ENEBLED' AND sgb.id_location = :locationId ";

            List<String> records = session.createSQLQuery(query)
                    .setParameter("date", date)
                    .setParameter("locationId", locationId)
                    .getResultList();

            if (records.isEmpty()) {
                success = false;
            }

            transaction.commit();

            logger.info("Total of stable general box found: " + records.size());
        } catch (HibernateException e) {
            logger.error("Can not find next stable general box by created on", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method existNextPaidStableGeneralBoxByCreatedOn()", e);
            rollback(transaction);
        }

        return success;
    }

    /**
     * Find stable general box between Dates (Start date and End Date).
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public List<StableGeneralBox> findStableGeneralBoxBetweenDates(Date startDate, Date endDate, String idLocation) {
        logger.info("findStableGeneralBoxBetweenDates");
        List<StableGeneralBox> results = null;
        Transaction transaction = null;
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaQuery<StableGeneralBox> query = builder.createQuery(StableGeneralBox.class);
            Root<StableGeneralBox> root = query.from(StableGeneralBox.class);

            Path<String> id = root.get("id");
            Path<BigDecimal> totalGeneralBox = root.get("totalGeneralBox");
            Path<BigDecimal> totalEnvelope = root.get("totalEnvelope");
            Path<BigDecimal> totalBankNote = root.get("totalBankNote");
            Path<BigDecimal> totalBank = root.get("totalBank");
            Path<BigDecimal> totalCoin = root.get("totalCoin");
            Path<BigDecimal> totalStable = root.get("totalStable");
            Path<String> description = root.get("description");
            Path<Date> createdOn = root.get("createdOn");
            Path<User> createdByPath = root.get("createdBy");
            Path<Location> locationPath = root.get("location");
            Path<Boolean> activeStatusPath = root.get("activeStatus");

            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(
                            StableGeneralBox.class,
                            id, totalGeneralBox, totalEnvelope,
                            totalBankNote, totalCoin, totalStable,
                            description, createdOn, createdByPath, locationPath, activeStatusPath, totalBank
                    )
            );
            query.where(builder.and(startDatePredicate, endDatePredicate, locationPredicate));
            query.orderBy(builder.asc(root.get("createdOn")));

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

            transaction.commit();

            logger.info("Stable General Box's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find stable general box between dates", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findStableGeneralBoxBetweenDates()", e);
            rollback(transaction);
        }
        return results;
    }

    /**
     * Update active status (ENEBLED/DISABLED) of stable general box by ID.
     *
     * @param id Primary key to be updated.
     * @param status Status to be updated (ENEBLED/DISABLED).
     * @param lastUpdatedBy User to apply update.
     * @return
     */
    public boolean updateStableGeneralBoxById(String id, BasicType status, User lastUpdatedBy) {
        logger.info("updateStableGeneralBoxById");

        boolean success = false;
        Transaction transaction = null;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            CriteriaBuilder builder = session.getCriteriaBuilder();
            CriteriaUpdate<StableGeneralBox> query = builder.createCriteriaUpdate(StableGeneralBox.class);
            Root<StableGeneralBox> root = query.from(StableGeneralBox.class);

            query.set(root.get("activeStatus"), status);
            query.set(root.get("lastUpdatedBy"), lastUpdatedBy);
            query.set(root.get("lastUpdatedOn"), new Date());

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

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

            if (1 == total) {
                transaction.commit();
                success = true;
                logger.info("Update status successfully");
            } else {
                logger.info("CAN NOT update stable general box");
                rollback(transaction);
            }
        } catch (HibernateException e) {
            logger.info("CAN NOT update stable general box", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method updateStableGeneralBoxById()", e);
            rollback(transaction);
        }
        return success;
    }

    /**
     * Save a new stable general box entry.
     *
     * @param stableGeneralBox
     * @return
     */
    public boolean saveStableGeneralBox(StableGeneralBox stableGeneralBox) {
        logger.info("saveStableGeneralBox");

        boolean success = false;
        Transaction transaction = null;

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

            session.save(stableGeneralBox);

            transaction.commit();
            success = true;
        } catch (HibernateException e) {
            logger.error("Can not save stable general box", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method saveStableGeneralBox()", e);
            rollback(transaction);
        }
        return success;
    }

    /**
     * Find an entry that match with date (dd/mm/yyyy).
     *
     * @param date
     * @param locationId
     * @return True if exist a coincidence otherwise false.
     */
    public boolean existStableGeneralBoxEqToDate(Date date, String locationId) {
        logger.info("existStableGeneralBoxEqToDate");

        boolean success = false;
        Transaction transaction = null;
// cuadre de caja general -> creaer un cuadre, poner cualqueir dato elegir fecha y creaer otro para comprobar

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            String queryStr = "SELECT COUNT(sgb.id) FROM StableGeneralBox sgb WHERE DATE(sgb.createdOn) = DATE(:date) AND sgb.activeStatus = 'ENEBLED' AND location = :location";

            Query query = session.createQuery(queryStr);
            query.setParameter("date", date);
            query.setParameter("location", new Location(locationId));
            success = (Long) (query.getSingleResult()) > 0;

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not load the stable general box", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method existStableGeneralBoxEqToDate()", e);
            rollback(transaction);
        }
        return success;
    }

    /**
     *
     * @return
     */
    public BigDecimal getTotalInBox(String idLocation) {
        logger.info("getTotalInBox");

        BigDecimal total = null;
        Transaction transaction = null;

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

            String sqlQuery = "SELECT\n"
                    + "(\n"
                    + "    (CASE\n"
                    + "        WHEN \n"
                    + "            (SELECT COUNT(total_general_box) AS total_in_box FROM stable_general_box WHERE DATE(created_on) < CURDATE() AND id_location = '"+idLocation+"' AND active_status = 'ENEBLED' ORDER BY created_on DESC LIMIT 1) > 0\n"
                    + "        THEN \n"
                    + "            (SELECT IF(ISNULL(total_general_box),0,total_general_box) AS total_in_box FROM stable_general_box WHERE DATE(created_on) < CURDATE() AND id_location = '"+idLocation+"' AND active_status = 'ENEBLED' ORDER BY created_on DESC LIMIT 1)\n"
                    + "        ELSE 0\n"
                    + "    END)\n"
                    + "    +\n"
                    + "    (SELECT IF(ISNULL(SUM(amount)),0,SUM(amount)) AS total_payment_in_today FROM expense_company WHERE expense_company_type = 'PAYMENT_IN' AND id_location = '"+idLocation+"' AND DATE(created_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1) AND active_status = 'ENEBLED')\n"
                    + "    -\n"
                    + "    (SELECT IF(ISNULL(SUM(amount)),0,SUM(amount)) AS total_payment_out_today FROM expense_company WHERE expense_company_type = 'PAYMENT_OUT' AND id_location = '"+idLocation+"' AND DATE(created_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1) AND active_status = 'ENEBLED')\n"
                    + "    -\n"
                    + "    (SELECT IF(ISNULL(SUM(payment)),0,SUM(payment)) AS payment FROM expense WHERE expense_type = 'INICIO' AND id_location = '"+idLocation+"' AND DATE(created_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1) AND expense_status_type = 'AUTHORIZED')\n"
                    + "    +\n"
                    + "    (SELECT IF(ISNULL(SUM(total_stable)),0,SUM(total_stable)) AS payment FROM stable_small_box WHERE active_status = 'ENEBLED' AND id_location = '"+idLocation+"' AND DATE(created_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1))\n"
                    + "     -\n"
                    + "    (SELECT IF(ISNULL(SUM(total)),0,SUM(total)) AS total FROM payroll WHERE active = 1 AND id_location = '"+idLocation+"' AND DATE(created_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1))\n"
                    + "     -\n"
                    + "     (SELECT IF(ISNULL(SUM(amount)),0,SUM(amount)) AS total_adelantos FROM adelantos WHERE id_location = '"+idLocation+"' AND DATE(created_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1) AND ACTIVE = 1) \n "
                    + "     +\n"
                    + "     (SELECT IF(ISNULL(SUM(amount)),0,SUM(amount)) AS total_transfer_receiver FROM transfer_money_location WHERE location_receiver = '"+idLocation+"' AND DATE(last_updated_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1) AND active = 1 AND autorizacion = 'ENEBLED') \n "
                    + "     -\n"
                    + "     (SELECT IF(ISNULL(SUM(amount)),0,SUM(amount)) AS total_transfer_send FROM transfer_money_location WHERE location_send = '"+idLocation+"' AND DATE(last_updated_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1) AND active = 1 AND autorizacion = 'ENEBLED') \n "
                    + "     -\n"
                    + "     (SELECT IF(ISNULL(SUM(es.payment)),0,SUM(es.payment)) AS total_payment FROM employee_sanction es INNER JOIN person p ON es.employee_id = p.id WHERE es.id_location = '"+idLocation+"' AND DATE(es.created_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1) AND es.active = 1 AND es.employee_sanction_type IN ('DISPOSICION_AHORRO', 'AGREGAR_DEUDA')) \n "
                    + "     +\n"
                    + "     (SELECT IF(ISNULL(SUM(es.payment)),0,SUM(es.payment)) AS total_payment FROM employee_sanction es INNER JOIN person p ON es.employee_id = p.id WHERE es.id_location = '"+idLocation+"' AND DATE(es.created_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1) AND es.active = 1 AND es.employee_sanction_type IN ('ABONO_DEUDA', 'SAVING')) \n "
                    + "     -\n"
                    + "     (SELECT IF(ISNULL(SUM(es.amount)),0,SUM(es.amount)) AS total_payment FROM taxes es WHERE es.id_location = '"+idLocation+"' AND DATE(es.created_on) > (SELECT DATE(sgb.created_on) FROM stable_general_box sgb WHERE DATE(sgb.created_on) < CURDATE() AND id_location = '"+idLocation+"' AND sgb.active_status = 'ENEBLED' ORDER BY sgb.created_on DESC LIMIT 1) AND es.active_status = 'ENEBLED') \n "
                    + "     \n"
                    + ")AS TOTAL FROM DUAL";

            NativeQuery nativeQuery = session.createSQLQuery(sqlQuery);

            Object totalObj = (Object) (nativeQuery.uniqueResult());

            if (totalObj instanceof Double) {
                total = BigDecimal.valueOf(((Double) totalObj));
            } else if (totalObj instanceof Float) {
                total = BigDecimal.valueOf(((Float) totalObj));
            } else if (totalObj instanceof Long) {
                total = BigDecimal.valueOf(((Long) totalObj));
            } else if (totalObj instanceof BigDecimal) {
                total = (BigDecimal) totalObj;
            } else {
                total = BigDecimal.ZERO;
            }

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not load the total in stable general box", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method getTotalInBox()", e);
            rollback(transaction);
        }

        return total;
    }
    
    public List<ClosingDay> findClosingDailyListByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findClosingDailyListByStableGeneralBox");

        List<ClosingDay> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            

            results = session.createQuery("FROM ClosingDay c WHERE c.activeStatus = 'ENEBLED' AND c.location.id = :idLocation AND DATE(c.createdOn) = DATE(:fecha) ")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("Closing daily detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find closing daily details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findDetailsFromClosingDayID()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public List<ExpenseCompany> findExpenseCompanyInListByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findExpenseCompanyInListByStableGeneralBox");

        List<ExpenseCompany> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            

            results = session.createQuery("FROM ExpenseCompany c WHERE c.activeStatus = 'ENEBLED' AND c.expenseCompanyType = 'PAYMENT_IN' "
                    + "AND c.location.id = :idLocation AND DATE(c.createdOn) = DATE(:fecha) ")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("ExpenseCompany in detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find ExpenseCompany in details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findExpenseCompanyInListByStableGeneralBox()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public List<ExpenseCompany> findExpenseCompanyOutListByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findExpenseCompanyOutListByStableGeneralBox");

        List<ExpenseCompany> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            

            results = session.createQuery("FROM ExpenseCompany c WHERE c.activeStatus = 'ENEBLED' AND c.expenseCompanyType = 'PAYMENT_OUT' "
                    + "AND c.location.id = :idLocation AND DATE(c.createdOn) = DATE(:fecha) ")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("ExpenseCompany out detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find ExpenseCompany out details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findExpenseCompanyOutListByStableGeneralBox()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public List<Payroll> findPayrollListByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findPayrollListByStableGeneralBox");

        List<Payroll> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            

            results = session.createQuery("FROM Payroll c WHERE c.active = 1 "
                    + "AND c.location.id = :idLocation AND DATE(c.createdOn) = DATE(:fecha) ")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("Payroll detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find Payroll details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findPayrollListByStableGeneralBox()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public List<Taxes> findTaxesListByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findTaxesListByStableGeneralBox");

        List<Taxes> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            

            results = session.createQuery("FROM Taxes c WHERE c.activeStatus = 'ENEBLED' "
                    + "AND c.location.id = :idLocation AND DATE(c.createdOn) = DATE(:fecha) ")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("Taxes detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find Taxes details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findTaxesListByStableGeneralBox()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public List<Expense> findIniciosListByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findIniciosListByStableGeneralBox");

        List<Expense> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            

            results = session.createQuery("FROM Expense c WHERE c.type = 'INICIO' "
                    + "AND c.location.id = :idLocation AND DATE(c.createdOn) = DATE(:fecha) ")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("Expense detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find Expense details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findIniciosListByStableGeneralBox()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public List<TransferMoneyLocation> findTransferListByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findTransferListByStableGeneralBox");

        List<TransferMoneyLocation> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            results = session.createQuery("FROM TransferMoneyLocation c WHERE c.autorizacion = 'ENEBLED' AND c.active = 1 "
                    + "AND (c.locationReceiver.id = :idLocation OR c.location.id = :idLocation) AND DATE(c.createdOn) = DATE(:fecha) ")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("TransferMoneyLocation detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find TransferMoneyLocation details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findTransferListByStableGeneralBox()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public List<Adelantos> findAdelantosListByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findAdelantosListByStableGeneralBox");

        List<Adelantos> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            results = session.createQuery("FROM Adelantos c WHERE c.active = 1 "
                    + "AND c.location.id = :idLocation AND DATE(c.createdOn) = DATE(:fecha) ")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("Adelantos detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find Adelantos details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findAdelantosListByStableGeneralBox()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public List<Sale> findSaleDepositByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findSaleDepositByStableGeneralBox");

        List<Sale> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            results = session.createQuery("FROM Sale c WHERE c.createdBy.location.id = :idLocation AND DATE(c.createdOn) = DATE(:fecha) AND c.transfer = 'ENEBLED'")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("Sale detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find Sale details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findSaleDepositByStableGeneralBox()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public List<EmployeeSanction> findEmployeeSanctionListByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findEmployeeSanctionListByStableGeneralBox");

        List<EmployeeSanction> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            results = session.createQuery("FROM EmployeeSanction c WHERE c.active = 1 "
                    + "AND c.location.id = :idLocation AND DATE(c.createdOn) = DATE(:fecha) AND c.type IN ('DISPOSICION_AHORRO', 'AGREGAR_DEUDA') ")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("EmployeeSanction detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find EmployeeSanction details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findEmployeeSanctionListByStableGeneralBox()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public List<ExpenseCompany> findExpenseCompanyAllListByStableGeneralBox(Date startDate, String idLocation) {
        logger.info("findExpenseCompanyAllListByStableGeneralBox");

        List<ExpenseCompany> results = null;
        Transaction transaction = null;
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();

            transaction = session.beginTransaction();
            
            

            results = session.createQuery("FROM ExpenseCompany c WHERE c.activeStatus = 'ENEBLED' AND c.expenseCompanyType IN ('PAYMENT_OUT', 'PAYMENT_IN') "
                    + "AND c.location.id = :idLocation AND DATE(c.createdOn) = DATE(:fecha) ")
                    .setParameter("idLocation", idLocation)
                    .setParameter("fecha", startDate)
                    .getResultList();

            transaction.commit();

            logger.info("ExpenseCompany all detail's list " + results.size());
        } catch (HibernateException e) {
            logger.error("Can not find ExpenseCompany all details list", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method findExpenseCompanyAllListByStableGeneralBox()", e);
            rollback(transaction);
        }
        return results;
    }
    
    public BigDecimal getLastStableGeneralBox(Date startDate, String idLocation) {
        logger.info("getLastStableGeneralBox");

        BigDecimal total = null;
        Transaction transaction = null;

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

            String sqlQuery = "SELECT\n"
                    + "(\n"
                    + "    (CASE\n"
                    + "        WHEN \n"
                    + "            (SELECT COUNT(total_general_box) AS total_in_box FROM stable_general_box WHERE DATE(created_on) < DATE('"+startDate+"') AND id_location = '"+idLocation+"' AND active_status = 'ENEBLED' ORDER BY created_on DESC LIMIT 1) > 0\n"
                    + "        THEN \n"
                    + "            (SELECT IF(ISNULL(total_general_box),0,total_general_box) AS total_in_box FROM stable_general_box WHERE DATE(created_on) < DATE('"+startDate+"') AND id_location = '"+idLocation+"' AND active_status = 'ENEBLED' ORDER BY created_on DESC LIMIT 1)\n"
                    + "        ELSE 0\n"
                    + "    END)\n"
                    + ")AS TOTAL FROM DUAL";

            NativeQuery nativeQuery = session.createSQLQuery(sqlQuery);

            Object totalObj = (Object) (nativeQuery.uniqueResult());

            if (totalObj instanceof Double) {
                total = BigDecimal.valueOf(((Double) totalObj));
            } else if (totalObj instanceof Float) {
                total = BigDecimal.valueOf(((Float) totalObj));
            } else if (totalObj instanceof Long) {
                total = BigDecimal.valueOf(((Long) totalObj));
            } else if (totalObj instanceof BigDecimal) {
                total = (BigDecimal) totalObj;
            } else {
                total = BigDecimal.ZERO;
            }

            transaction.commit();
        } catch (HibernateException e) {
            logger.error("Can not load the last stable general box", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method getLastStableGeneralBox()", e);
            rollback(transaction);
        }

        return total;
    }

    private static final long serialVersionUID = 895942543381249792L;
    final Logger logger = LogManager.getLogger(StableGeneralBoxController.class);
}
