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

import com.arrebol.taxiservicios.controller.connection.ConnectionManager;
import com.arrebol.taxiservicios.controller.util.HibernateUtil;
import com.arrebol.taxiservicios.model.catalog.Brand;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.catalog.Product;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.arrebol.taxiservicios.model.stocktaking.ChangeAmountProduct;
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.CriteriaUpdate;
import javax.persistence.criteria.Path;
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 ChangeAmountProductController extends ConnectionManager implements Serializable {
    
    public List<Product> fillProductsComboBox() {

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

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

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

            Path<String> idPath = root.get("id");
            Path<String> namePath = root.get("name");
            Path<String> codePath = root.get("code");
            Path<Brand> brandPath = root.get("brand");
            Path<Double> amount = root.get("amount");
            Path<Integer> quantity = root.get("quantity");

            criteria.select(
                    builder.construct(Product.class, idPath, namePath, codePath, brandPath, amount, quantity
                    ));
            criteria.where(builder.equal(root.get("activeStatus"), BasicType.ENEBLED));

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

            logger.info("Total of products found for ComboBox: " + (null == result ? -1 : result.size()));
            transaction.commit();
        } catch (HibernateException e) {
            rollback(transaction);
            logger.error("Can not load list of products for ComboBox ", e);
        } catch (Exception e) {
            rollback(transaction);
            logger.error("Method fillProductsComboBox for Invoice", e);
        }

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

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

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

            results = session.createQuery("FROM ChangeAmountProduct WHERE active = :active AND (DATE(createdOn) BETWEEN DATE(:starDate) AND DATE(:endDate)) AND location.id = :location  ORDER BY createdOn DESC")
                    .setParameter("starDate", starDate)
                    .setParameter("endDate", endDate)
                    .setParameter("location", location.getId())
                    .setParameter("active", true)
                    .getResultList();

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

        return results;
    }
    
    public ChangeAmountProduct findById(String id) {
        ChangeAmountProduct result = null;
        Transaction transaction = null;

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

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

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

        return result;
    }
    
    public Product findProductById(String id) {
        Product result = null;
        Transaction transaction = null;

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

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

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

        return result;
    }
    
    public boolean save(ChangeAmountProduct change, Product product) {
        logger.info("save");

        boolean success = false;
        Transaction transaction = null;

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

            session.save(change);
            logger.info("change saved " + change.getId());

            if(change.getLocation().getId().equalsIgnoreCase("4d0859be-e31a-4acb-a690-2a5c2cb027a7"))
            {
                product.setAmount(change.getAmount());
                session.update(product);
            }
            else
            {
                product.setAmount2(change.getAmount());
                session.update(product);
            }

            transaction.commit();

            success = true;
        } catch (HibernateException e) {
            logger.error("Invoice can not be added ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method saveInvoice() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    public boolean updateProductAmountById(Product product) {
        logger.info("updateProductAmountById");

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

            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaUpdate<Product> update = builder.createCriteriaUpdate(Product.class);
            Root<Product> rootUpdate = update.from(Product.class);

            update.set("amount", product.getAmount());
            update.set("amount2", product.getAmount2());
            update.set("lastUpdatedOn", new Date());
            update.where(builder.equal(rootUpdate.get("id"), product.getId()));

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

            if (1 == total) {
                transaction.commit();
                success = true;
                logger.info("Product " + product.getId() + " updated");
            } else {
                transaction.rollback();
                logger.error("Error product updated total: " + total);
            }
        } catch (HibernateException e) {
            logger.error("Taxi can not be updated ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method updateProductAmountById() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    public boolean deleteChangeProductAmountById(ChangeAmountProduct changeAmountProduct) {
        logger.info("deleteChangeProductAmountById");

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

            CriteriaBuilder builder = session.getCriteriaBuilder();

            CriteriaUpdate<ChangeAmountProduct> update = builder.createCriteriaUpdate(ChangeAmountProduct.class);
            Root<ChangeAmountProduct> rootUpdate = update.from(ChangeAmountProduct.class);

            update.set("active", false);
            update.set("lastUpdatedOn", new Date());
            update.where(builder.equal(rootUpdate.get("id"), changeAmountProduct.getId()));

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

            if (1 == total) {
                transaction.commit();
                success = true;
                logger.info("changeAmountProduct " + changeAmountProduct.getId() + " deleted");
            } else {
                transaction.rollback();
                logger.error("Error changeAmountProduct deleted total: " + total);
            }
        } catch (HibernateException e) {
            logger.error("changeAmountProduct can not be deleted ", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method deleteChangeProductAmountById() ", e);
            rollback(transaction);
        }
        return success;
    }
    
    final Logger logger = LogManager.getLogger(ChangeAmountProductController.class);

    public ChangeAmountProductController() {
    }
    
}
