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

import com.arrebol.apc.controller.util.ConnectionManager;
import com.arrebol.apc.controller.util.HibernateUtil;
import com.arrebol.apc.model.ModelParameter;
import com.arrebol.apc.model.admin.constance.GoalCfg;
import com.arrebol.apc.model.views.StatsPayrollView;
import com.arrebol.apc.model.views.StatsSummaryView;
import com.arrebol.apc.repository.GenericEntityRepository;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.arrebol.apc.model.views.constance.StatsPayrollViewCfg;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author David Rodriguez
 */
public class StatsSummaryController extends ConnectionManager implements Serializable {

    public List<StatsSummaryView> fillSummaryDataTable(Date startDate, Date endDate) {
        logger.debug("fillSummaryDataTable");
        List<StatsSummaryView> dataList = new ArrayList<>();
        Transaction transaction = null;
        
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        startDate = calendar.getTime();

        Calendar calendarF = Calendar.getInstance();
        calendarF.setTime(endDate);
        calendarF.add(Calendar.DAY_OF_YEAR, 1);
        endDate = calendarF.getTime();
        
        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            transaction = session.beginTransaction();
            SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

            List<Object> rows = session.createNativeQuery(querySummary)
                    .setParameter("startDate", startDate)
                    .setParameter("endDate", endDate)
                    .getResultList();

            transaction.commit();

            rows.forEach((row) -> {
                Object[] results = (Object[]) row;

                // Create Data Row
                StatsSummaryView summaryRow = new StatsSummaryView();
                summaryRow.setIdUser(results[0] == null ? "" : results[0].toString());
                summaryRow.setUserName(results[1] == null ? "" : results[1].toString());
                summaryRow.setOpeningFee(new BigDecimal(results[2] == null ? "0.0" : results[2].toString()));
                summaryRow.setDeposits(new BigDecimal(results[3] == null ? "0.0" : results[3].toString()));
                summaryRow.setPayment(new BigDecimal(results[4] == null ? "0.0" : results[4].toString()));
                summaryRow.setPayroll(new BigDecimal(results[5] == null ? "0.0" : results[5].toString()));
                summaryRow.setGasoline(new BigDecimal(results[6] == null ? "0.0" : results[6].toString()));
                summaryRow.setAdvances(new BigDecimal(results[7] == null ? "0.0" : results[7].toString()));
                summaryRow.setExpenses(new BigDecimal(results[8] == null ? "0.0" : results[8].toString()));
                summaryRow.setTrasferTransmitter(new BigDecimal(results[9] == null ? "0.0" : results[9].toString()));
                summaryRow.setTrasferReceiver(new BigDecimal(results[10] == null ? "0.0" : results[10].toString()));

                dataList.add(summaryRow);
            });

        } catch (HibernateException e) {
            logger.error("Driver", e);
            rollback(transaction);
        } catch (Exception e) {
            logger.error("Method fillSummaryDataTable(" + startDate + " " + ") ", e);
            rollback(transaction);
        }

        return dataList;
    }

    public BigDecimal fillTotalSummary(Date startDate, Date endDate) {
        logger.debug("fillTotalSummary");
        List<ModelParameter> parameters = new ArrayList<>();
        
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        startDate = calendar.getTime();

        Calendar calendarF = Calendar.getInstance();
        calendarF.setTime(endDate);
        calendarF.add(Calendar.DAY_OF_YEAR, 1);
        endDate = calendarF.getTime();
        
        parameters.add(new ModelParameter(GoalCfg.PARAM_START_DATE, startDate));
        parameters.add(new ModelParameter(GoalCfg.PARAM_END_DATE, endDate));
        List<StatsPayrollView> dataComplete = genericEntityRepository.xmlQueryAPCEntities(StatsPayrollView.class, StatsPayrollViewCfg.QUERY_FIND_ALL_PAYROLL_BETWEEN_DATES, parameters);
        BigDecimal totalPayroll = new BigDecimal("0");
        for (StatsPayrollView payroll : dataComplete) {
            totalPayroll = totalPayroll.add(payroll.getTotalPayroll());
        }
        return totalPayroll;
    }

    final Logger logger = LogManager.getLogger(StatsSummaryController.class);
    private final GenericEntityRepository genericEntityRepository;

    public StatsSummaryController() {
        this.genericEntityRepository = new GenericEntityRepository();
    }
    
    private final String querySummary
            = "SELECT  "
            + " HR.id AS id_user, "
            + "	CONCAT(HR.first_name, ' ', HR.last_name) AS Name, "
            + "    IFNULL(OFE.opening_fee, 0.0) AS opening_fee, "
            + "    IFNULL(DEP.total_deposits, 0.0) AS deposits, "
            + "    IFNULL(PAY.total_payment, 0.0) AS payment, "
            + "    IFNULL(PR.total_payroll, 0.0) AS payroll, "
            + "    IFNULL(GAS.total_gasoline, 0.0) AS gasoline, "
            + "    IFNULL(ADV.total_advances, 0.0) AS advances, "
            + "    IFNULL(EXP.total_expenses, 0.0) AS expenses, "
            + "	IFNULL(TE.total_transfer, 0.0) AS trasfer_transmitter, "
            + "    IFNULL(TR.total_transfer, 0.0) AS trasfer_receiver "
            + "FROM APC_HUMAN_RESOURCE AS HR "
            + "INNER JOIN APC_USER AS U ON U.id_human_resource = HR.Id "
            + "LEFT JOIN "
            + "( "
            + "	SELECT "
            + "		HR.id AS id_HR, CONCAT(HR.first_name, ' ', HR.last_name) AS Name, SUM(LT.opening_fee) AS opening_fee "
            + "	FROM APC_LOAN L "
            + "	INNER JOIN APC_LOAN_TYPE LT ON L.id_loan_type = LT.id "
            + "	INNER JOIN APC_USER U ON L.created_by = U.id "
            + "	INNER JOIN APC_HUMAN_RESOURCE HR ON U.id_human_resource = HR.id "
            + "    WHERE DATE(L.created_on) BETWEEN DATE(:startDate) AND DATE(:endDate) "
            + "	GROUP BY HR.id "
            + ") OFE ON HR.id = OFE.id_HR "
            + "LEFT JOIN "
            + "( "
            + "	SELECT "
            + "		HR.id AS id_HR, CONCAT(HR.first_name, ' ', HR.last_name) AS Name, SUM(LD.payment_amount )AS total_deposits "
            + "	FROM APC_LOAN_DETAIL LD "
            + "	INNER JOIN APC_LOAN L ON LD.id_loan = L.id AND L.loan_status <> 'DELETED' "
            + "	INNER JOIN APC_USER U ON LD.id_user = U.id "
            + "	INNER JOIN APC_HUMAN_RESOURCE HR ON U.id_human_resource = HR.id "
            + "	WHERE loan_details_type IN ('TRANSFER') AND DATE(LD.created_on) BETWEEN DATE(:startDate) AND DATE(:endDate) "
            + "	GROUP BY HR.id "
            + ") DEP ON HR.id = DEP.id_HR "
            + "LEFT JOIN "
            + "( "
            + "	SELECT "
            + "		HR.id AS id_HR, CONCAT(HR.first_name, ' ', HR.last_name) AS Name, SUM(LD.payment_amount )AS total_payment "
            + "	FROM APC_LOAN_DETAIL LD "
            + "	INNER JOIN APC_LOAN L ON LD.id_loan = L.id AND L.loan_status <> 'DELETED' "
            + "	INNER JOIN APC_USER U ON LD.id_user = U.id "
            + "	INNER JOIN APC_HUMAN_RESOURCE HR ON U.id_human_resource = HR.id "
            + "	WHERE loan_details_type IN ('PAYMENT') AND DATE(LD.created_on) BETWEEN DATE(:startDate) AND DATE(:endDate) "
            + "	GROUP BY HR.id "
            + ") PAY ON HR.id = PAY.id_HR "
            + "LEFT JOIN "
            + "( "
            + "	SELECT  "
            + "		P.id_human_resource AS id_HR, "
            + "		SUM(P.salary + P.total_bonus_colocation + P.total_bonus_mora + P.total_bonus_new_customer + P.increases) AS total_payroll "
            + "	FROM APC_PAYROLL P "
            + "    WHERE DATE(P.created_on) BETWEEN DATE(:startDate) AND DATE(:endDate) "
            + "    GROUP BY P.id_human_resource "
            + ")PR ON HR.id = PR.id_HR "
            + "LEFT JOIN "
            + "( "
            + "	SELECT "
            + "		HR.id AS id_HR, CONCAT(HR.first_name, ' ', HR.last_name) AS user_name, SUM(G.total) AS total_gasoline "
            + "	FROM APC_GASOLINE G "
            + "	INNER JOIN APC_USER U ON G.id_user = U.id "
            + "	INNER JOIN APC_HUMAN_RESOURCE HR ON U.id_human_resource = HR.id "
            + "	WHERE G.status = 'ENABLED' AND DATE(G.created_on) BETWEEN DATE(:startDate) AND DATE(:endDate) "
            + "	GROUP BY HR.id "
            + ")GAS ON HR.id = GAS.id_HR "
            + "LEFT JOIN "
            + "( "
            + "	SELECT "
            + "		HR.id AS id_HR, SUM(LD.payment_amount) AS total_advances "
            + "	FROM APC_LOAN_DETAIL LD "
            + "	INNER JOIN APC_LOAN L ON LD.id_loan = L.id AND L.loan_status <> 'DELETED' "
            + "	INNER JOIN APC_USER U ON LD.id_user = U.id "
            + "	INNER JOIN APC_HUMAN_RESOURCE HR ON U.id_human_resource = HR.id "
            + "	WHERE loan_details_type IN ('RENOVATION_PAYMENT') AND DATE(LD.created_on) BETWEEN DATE(:startDate) AND DATE(:endDate) "
            + "	GROUP BY HR.id "
            + ")ADV ON HR.id = ADV.id_HR "
            + "LEFT JOIN "
            + "( "
            + "	SELECT  "
            + "		HR.id AS id_HR, CONCAT(HR.first_name, ' ', HR.last_name) AS user_name, SUM(OE.expense) AS total_expenses "
            + "	FROM APC_OTHER_EXPENSE OE "
            + "	INNER JOIN APC_USER U ON OE.id_user = U.id "
            + "	INNER JOIN APC_HUMAN_RESOURCE HR ON U.id_human_resource = HR.id "
            + "    WHERE DATE(OE.created_on) BETWEEN DATE(:startDate) AND DATE(:endDate) "
            + "	GROUP BY HR.id "
            + ")EXP ON HR.id = EXP.id_HR "
            + "LEFT JOIN "
            + "( "
            + "	SELECT  "
            + "		HR.id AS id_HR, CONCAT(HR.first_name, ' ', HR.last_name) AS user_name, SUM(TE.amount_to_transfer) AS total_transfer "
            + "	FROM APC_TRANSFER TE "
            + "	INNER JOIN APC_USER U ON TE.id_user_transmitter = U.id "
            + "	INNER JOIN APC_HUMAN_RESOURCE HR ON U.id_human_resource = HR.id "
            + "    WHERE DATE(TE.created_on) BETWEEN DATE(:startDate) AND DATE(:endDate) "
            + "	GROUP BY HR.id "
            + ")TE ON HR.id = TE.id_HR "
            + "LEFT JOIN "
            + "( "
            + "	SELECT  "
            + "		HR.id AS id_HR, CONCAT(HR.first_name, ' ', HR.last_name) AS user_name, SUM(TR.amount_to_transfer) AS total_transfer "
            + "	FROM APC_TRANSFER TR "
            + "	INNER JOIN APC_USER U ON TR.id_user_receiver = U.id "
            + "	INNER JOIN APC_HUMAN_RESOURCE HR ON U.id_human_resource = HR.id "
            + "    WHERE DATE(TR.created_on) BETWEEN DATE(:startDate) AND DATE(:endDate) "
            + "	GROUP BY HR.id "
            + ")TR ON HR.id = TR.id_HR "
            + "WHERE HR.human_resource_status = 'ENEBLED';";
}
