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

import com.arrebol.apc.controller.BitacoraController;
import com.arrebol.apc.controller.GenericController;
import com.arrebol.apc.controller.GenericValidationController;
import com.arrebol.apc.controller.admin.LoanEmployeeController;
import com.arrebol.apc.controller.admin.PayRollController;
import com.arrebol.apc.controller.drive.DriverController;
import com.arrebol.apc.model.admin.EmployeeSaving;
import com.arrebol.apc.model.admin.Goal;
import com.arrebol.apc.model.admin.LoanEmployee;
import com.arrebol.apc.model.admin.LoanEmployeeDetails;
import com.arrebol.apc.model.admin.StableGeneralBox;
import com.arrebol.apc.model.core.HumanResource;
import com.arrebol.apc.model.core.Office;
import com.arrebol.apc.model.core.User;
import com.arrebol.apc.model.enums.ActiveStatus;
import com.arrebol.apc.model.enums.EmployeeSavingType;
import com.arrebol.apc.model.loan.Loan;
import com.arrebol.apc.model.payroll.Payroll;
import com.arrebol.apc.model.system.logs.Bitacora;
import com.arrebol.apc.model.views.InformationLoanLastWeekView;
import com.arrebol.apc.model.views.LoanEmployeeView;
import com.arrebol.apc.web.beans.Datatable;
import com.arrebol.apc.web.beans.GenericBean;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.event.ReorderEvent;
import org.primefaces.event.RowEditEvent;

/**
 *
 * @author Oscar Armando Vargas Cardenas <oscar.vargas@arrebol.com.mx>
 */
@Named("payrollManager")
@ViewScoped
public class PayRollBean extends GenericBean implements Serializable, Datatable {

    public void searchHistoricalAction() {
        try {
            if (getStarDate().after(getEndDate())) {
                showMessage(FacesMessage.SEVERITY_ERROR, getBundlePropertyFile().getString("generic.start.date"), getBundlePropertyFile().getString("generic.end.date.error"));
            } else {
                setPayroll(getPayrollCtrl().fillPayrollDatatable(getLoggedUser().getOffice().getId(), getStarDate(), getEndDate()));
            }
        } catch (Exception e) {
        }
    }

    public List<User> getUsers() {

        return genericCtrl.getAllUsersByOffice(getLoggedUser().getOffice().getId());
    }

    public void calculationFunction() {
        total = BigDecimal.ZERO;
        BigDecimal moraDiscount = BonusMora.divide(new BigDecimal(5)).multiply(new BigDecimal(daysBonus));
        BigDecimal colocationDiscount = bonusColocation.divide(new BigDecimal(5)).multiply(new BigDecimal(daysBonus));
        BigDecimal salaryDiscount = salary.divide(new BigDecimal(5)).multiply(new BigDecimal(daysSalary));
        granTotalDeducciones = imss.add(advances).add(discounts).add(boxed).add(saving).add(paymentToDebt);
        total = total.add(salaryDiscount).add(moraDiscount).add(colocationDiscount).add(newCustomer)
                .subtract(imss).subtract(advances).subtract(discounts).subtract(boxed).subtract(saving).subtract(paymentToDebt).add(increases);
    }

    public void getResumenByUser() {

        salary = BigDecimal.ZERO;
        imss = BigDecimal.ZERO;
        advances = BigDecimal.ZERO;
        newCustomer = BigDecimal.ZERO;
        bonusColocation = BigDecimal.ZERO;
        BonusMora = BigDecimal.ZERO;
        granTotal = BigDecimal.ZERO;
        granTotalDeducciones = BigDecimal.ZERO;
        total = BigDecimal.ZERO;
        discounts = BigDecimal.ZERO;
        increases = BigDecimal.ZERO;
        metaInfo = BigDecimal.ZERO;
        newCustomerInfo = BigDecimal.ZERO;
        toalColocadoInfo = BigDecimal.ZERO;
        toalPaymentInfo = BigDecimal.ZERO;
        toalFeeInfo = BigDecimal.ZERO;
        saldoInsoluto = BigDecimal.ZERO;
        bonusNewCustomerInfo = BigDecimal.ZERO;
        bonusColocationInfo = BigDecimal.ZERO;
        bonusMoraInfo = BigDecimal.ZERO;
        tipoBonusInfo = "";
        commentsDiscounts = "";
        commentsIncreases = "";
        commentsIncreases = "";
        boxed = BigDecimal.ZERO;
        saving = BigDecimal.ZERO;
        paymentToDebt = BigDecimal.ZERO;
        BigDecimal divider;

        if (userId == null || userId.isEmpty()) {
            showMessage(FacesMessage.SEVERITY_WARN, "Empleado obligatorio", "Debes seleccionar un empleado para calcular la nómina");
            userId = "";
            return;
        }

        if (dateInit == null || dateEnd == null) {
            showMessage(FacesMessage.SEVERITY_WARN, "Fechas obligatorias", "Debes seleccionar las fechas para calcular la nómina");
            userId = "";
            return;
        }

        User userPayRoll = payrollCtrl.getUserById(userId);
        if (userPayRoll != null) {
            if (userPayRoll.getHumanResource().getBonus() == null) {
                showMessage(FacesMessage.SEVERITY_WARN, "Usuario incompleto", "El empleado no tiene un bono registrado, es obligatorio tenerlo registrado");
                userId = "";
                return;
            }
            //obtengo salario del empleado
            salary = userPayRoll.getHumanResource().getPayment();
            //obtengo imss del empleado
            imss = userPayRoll.getHumanResource().getImss();
            //Lleno la información de los bonos *** INFORMATIVO
            bonusColocationInfo = userPayRoll.getHumanResource().getBonus().getLoanBonus();
            bonusMoraInfo = userPayRoll.getHumanResource().getBonus().getMoraBonus();
            bonusNewCustomerInfo = userPayRoll.getHumanResource().getBonus().getNewCustomerBonus();
            tipoBonusInfo = userPayRoll.getHumanResource().getBonus().getAdministrative() == ActiveStatus.ENEBLED ? "Administrativo" : "Operativo";
            //Obtengo todos los adelantos que tuvo el usuario en las fechas dadas y que esten activos.
            Date fechaAdvance = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(fechaAdvance); // Configuramos la fecha que se recibe
            calendar.add(Calendar.DAY_OF_YEAR, -6);

            advances = payrollCtrl.getSumAdvanceByUser(userPayRoll.getHumanResource().getId(), getLoggedUser().getOffice().getId(), calendar.getTime(), fechaAdvance);
            
            if (saving.compareTo(BigDecimal.ZERO) == 0) {
                saving = userPayRoll.getHumanResource().getEmployeeSaving();
            }
            
            if (advances == null) {
                advances = BigDecimal.ZERO;
            }

            //Valido que el bono del usuario no sea administrativo, ya que el bono de clientes nuevos solo se paga a asesores y certificadores, de
            //lo contrario va en 0
            if (userPayRoll.getHumanResource().getBonus().getAdministrative() == ActiveStatus.DISABLED) {
                //Obtengo cuantos prestamos con clientes nuevos dio de alta el asesor en esas fechas y lo multiplico por el valor del bono de clientes nuevos
                List<Loan> loansNew = payrollCtrl.getTotalNewCustomerLoansByUser(userId, dateInit, dateEnd);
                int contador = 0;
                for (Loan loan : loansNew) {
                    newCustomer = newCustomer.add((loan.getLoanType().getPayment().divide(new BigDecimal(1000))).multiply(userPayRoll.getHumanResource().getBonus().getNewCustomerBonus()));
                    contador++;
                }
                newCustomerInfo = newCustomerInfo.add(new BigDecimal(contador));
            }

            //Obtengo la meta que consta de esas fechas
            //goal = payrollCtrl.getGoalByDates(getLoggedUser().getOffice().getId(), dateInit, dateEnd);
            // La meta se obtiene de la última capturada
            goal = payrollCtrl.getLastGoal(getLoggedUser().getOffice().getId());
            metaInfo = goal.getAmount();

            // Se llena el control de abono a deuda
            List<LoanEmployeeView> loanEmployeeList = payrollCtrl.getPaymentToDebtByUser(userPayRoll.getHumanResource().getId());
            if (loanEmployeeList != null && !loanEmployeeList.isEmpty()) {
                loanEmployeeList.forEach((loanEmployee) -> {
                    saldoInsoluto = saldoInsoluto.add(loanEmployee.getBalance());
                    if(loanEmployee.getBalance().compareTo(loanEmployee.getAmountToPay()) < 0){
                        if (loanEmployee.getBalance().compareTo(BigDecimal.ZERO) > 0) {
                            paymentToDebt = paymentToDebt.add(loanEmployee.getBalance());
                        }
                    }else{
                        paymentToDebt = paymentToDebt.add(loanEmployee.getAmountToPay());
                    }
                });
            }

            //********Bono de colocación*********
            //Obtengo el total del monto colocado por usuario en esas fechas.
            BigDecimal amountColocationByUser = payrollCtrl.getTotalLoansByUserForDates(userId, dateInit, dateEnd);
            toalColocadoInfo = amountColocationByUser;

            //Valido que si halla obtenido una meta y que el bono del empleado no sea administrativo para calcular el bono por colocacion.
            if (goal != null && amountColocationByUser != null && userPayRoll.getHumanResource().getBonus().getAdministrative() == ActiveStatus.DISABLED) {
                BigDecimal maxPorcentaje = new BigDecimal(100);
                BigDecimal minPorcentaje = new BigDecimal(80);
                BigDecimal porcentaje = (amountColocationByUser.multiply(maxPorcentaje)).divide(goal.getAmount(), 2, RoundingMode.HALF_UP);

                if (porcentaje != null) {
                    if (porcentaje.compareTo(minPorcentaje) == -1) {
                        bonusColocation = BigDecimal.ZERO;
                    }
                    if (porcentaje.compareTo(minPorcentaje.subtract(BigDecimal.ONE)) == 1 && porcentaje.compareTo(maxPorcentaje) == -1) {
                        bonusColocation = ((goal.getAmount().multiply(userPayRoll.getHumanResource().getBonus().getLoanBonus())).divide(maxPorcentaje)).divide(new BigDecimal(2));
                    }
                    if (porcentaje.compareTo(maxPorcentaje) == 0 || porcentaje.compareTo(maxPorcentaje) == 1) {
                        bonusColocation = (goal.getAmount().multiply(userPayRoll.getHumanResource().getBonus().getLoanBonus())).divide(maxPorcentaje);
                    }
                }

            }
            if (userPayRoll.getHumanResource().getBonus().getAdministrative() == ActiveStatus.ENEBLED) {
                bonusColocation = userPayRoll.getHumanResource().getBonus().getLoanBonus();
            }

            //********Bono de mora*********
            //Obtengo todos los abonos por usuario en ese rango de fechas
            BigDecimal amountPayments = payrollCtrl.getLoanDetailsByUserForDates(userId, dateInit, dateEnd);
            Long openingFee = payrollCtrl.getTotalOpeningFeeByUser(userId, dateInit, dateEnd);

            //Obtengo todas las multas por usuario en ese rango de fechas
            //BigDecimal amountFee = payrollCtrl.getFeeByUserForDates(userId, dateInit, dateEnd);
            //**************************
            Double sumFaltante = data.stream().filter(p -> p.getIdUser().equalsIgnoreCase(userId)).mapToDouble(h -> h.getFaltante().doubleValue()).sum();
            BigDecimal amountFee = BigDecimal.valueOf(sumFaltante);
            //**************************

            if (openingFee == null) {
                openingFee = 0L;
            }
            if (amountPayments == null) {
                amountPayments = BigDecimal.ZERO;
            }
            if (amountFee == null) {
                amountFee = BigDecimal.ZERO;
            }
            amountPayments = amountPayments.add(BigDecimal.valueOf(openingFee));
            toalPaymentInfo = amountPayments;
            toalFeeInfo = amountFee;

            if (userPayRoll.getHumanResource().getBonus().getAdministrative() == ActiveStatus.ENEBLED) {
                BonusMora = userPayRoll.getHumanResource().getBonus().getMoraBonus();
            } else {
                if (amountPayments.compareTo(BigDecimal.ZERO) == 1) {
                    BigDecimal totalPorcentaje = new BigDecimal(100);
                    BigDecimal maxPorcentaje = new BigDecimal(2);
                    BigDecimal middlePorcentaje = new BigDecimal(1);
                    if (amountFee.compareTo(BigDecimal.ZERO) == 0 || amountFee.compareTo(BigDecimal.ZERO) < 0) {
                        BonusMora = (amountPayments.multiply(userPayRoll.getHumanResource().getBonus().getMoraBonus()));
                    } else {
                        
                        if(payrollCtrl.getTotalExpectedWeekByUser(userId)==null){
                            
                            divider = BigDecimal.ONE;
                        }else{
                            divider = payrollCtrl.getTotalExpectedWeekByUser(userId);
                        }
                        
                        
                        BigDecimal porcentaje = (amountFee.multiply(totalPorcentaje)).divide(divider, 2, RoundingMode.HALF_UP);
                        if (porcentaje.compareTo(maxPorcentaje) == 0 || porcentaje.compareTo(maxPorcentaje) == 1) {
                            BonusMora = BigDecimal.ZERO;
                        }
                        if ((porcentaje.compareTo(BigDecimal.ZERO) == 0) || (porcentaje.compareTo(BigDecimal.ZERO) == 1 && porcentaje.compareTo(middlePorcentaje) == -1)) {
                            BonusMora = (amountPayments.multiply(userPayRoll.getHumanResource().getBonus().getMoraBonus()));
                        }
                        if ((porcentaje.compareTo(middlePorcentaje) == 0) || (porcentaje.compareTo(middlePorcentaje) == 1 && porcentaje.compareTo(maxPorcentaje) == -1)) {
                            BonusMora = (amountPayments.multiply(userPayRoll.getHumanResource().getBonus().getMoraBonus())).divide(maxPorcentaje);
                        }
                    }

                }
            }
            boxed = payrollCtrl.getDiscountByUserThisWeek(userId);
            if (boxed == null || boxed.compareTo(BigDecimal.ZERO) < 0) {
                boxed = BigDecimal.ZERO;
            }
            /* Se comenta debido a que el campo cajeado toma el valor
            else {
                commentsDiscounts = "Descuentos por cajeado en cortes del día";
            }*/
            granTotal = salary.add(BonusMora).add(bonusColocation).add(newCustomer).subtract(advances);
            granTotalDeducciones = imss.add(advances).add(discounts).add(boxed).add(saving).add(paymentToDebt);
            total = granTotal.subtract(boxed).subtract(imss).subtract(saving).subtract(paymentToDebt);
        }
    }

    @Override
    public void editRow(RowEditEvent event) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void onRowCancel(RowEditEvent event) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void onRowReorder(ReorderEvent event) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void addRow() {
        if (userId == null || userId.isEmpty()) {
            showMessage(FacesMessage.SEVERITY_WARN, "Empleado obligatorio", "Debes seleccionar un empleado para calcular la nómina");
            userId = "";
            return;
        }

        if (dateInit == null || dateEnd == null) {
            showMessage(FacesMessage.SEVERITY_WARN, "Fechas obligatorias", "Debes seleccionar las fechas para calcular la nómina");
            userId = "";
            return;
        }
        
        
        if (genericCtrl.existStableGeneralBoxByCreatedOn(new Date())) {
            showMessage(FacesMessage.SEVERITY_WARN, "Día cerrado", "No se pueden crear mas nominas porque ya se existe un cuadre de caja general de hoy.");
            return;
        }

         
        Payroll payroll = new Payroll();

        User userPayRoll = payrollCtrl.getUserById(userId);

        payroll.setActiveStatus(ActiveStatus.ENEBLED);
        payroll.setAdvance(advances);
        payroll.setCommentsDiscounts(commentsDiscounts);
        payroll.setCommentsIncreases(commentsIncreases);
        payroll.setCreatedBy(getLoggedUser().getUser().getId());
        payroll.setCreatedOn(new Date());
        payroll.setDiscounts(discounts);
        payroll.setHumanResource(userPayRoll.getHumanResource());
        payroll.setImss(imss);
        payroll.setIncreases(increases);
        payroll.setObservation(comments);
        payroll.setOffice(new Office(getLoggedUser().getOffice().getId()));
        payroll.setSalary(salary);
        payroll.setTotalBonusColocation(bonusColocation);
        payroll.setTotalBonusMora(BonusMora);
        payroll.setTotalBonusNewCustomer(newCustomer);
        payroll.setTotalDaysBonus(daysBonus);
        payroll.setTotalDaysSalary(daysSalary);
        payroll.setTotalPayment(total);
        payroll.setBoxed(boxed);
        payroll.setSaving(saving);
        payroll.setPaymentToDebt(paymentToDebt);

        // ADD new Fields values
        
        if (payrollCtrl.savePayroll(payroll)) {
            createPaymentLoanEmployee(userPayRoll.getHumanResource());
            // Guarda el registro en la tabla de ahorro
            if (saving.compareTo(BigDecimal.ZERO) > 0) {
                createEmployeeSaving(userPayRoll.getHumanResource());
            }
            
            FacesMessage msg = new FacesMessage("Nómina creada.", "Se registró la nómina correctamente.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
            salary = BigDecimal.ZERO;
            imss = BigDecimal.ZERO;
            advances = BigDecimal.ZERO;
            newCustomer = BigDecimal.ZERO;
            bonusColocation = BigDecimal.ZERO;
            BonusMora = BigDecimal.ZERO;
            granTotal = BigDecimal.ZERO;
            granTotalDeducciones = BigDecimal.ZERO;
            total = BigDecimal.ZERO;
            discounts = BigDecimal.ZERO;
            increases = BigDecimal.ZERO;
            metaInfo = BigDecimal.ZERO;
            newCustomerInfo = BigDecimal.ZERO;
            toalColocadoInfo = BigDecimal.ZERO;
            toalPaymentInfo = BigDecimal.ZERO;
            toalFeeInfo = BigDecimal.ZERO;
            saldoInsoluto = BigDecimal.ZERO;
            bonusNewCustomerInfo = BigDecimal.ZERO;
            bonusColocationInfo = BigDecimal.ZERO;
            bonusMoraInfo = BigDecimal.ZERO;
            tipoBonusInfo = "";
            commentsDiscounts = "";
            commentsIncreases = "";
            comments = "";
            userId = "";
            boxed = BigDecimal.ZERO;
            saving = BigDecimal.ZERO;
            paymentToDebt = BigDecimal.ZERO;
        }

    }

    private void createPaymentLoanEmployee(HumanResource humanResource) {
        List<LoanEmployeeView> loanEmployeeList = payrollCtrl.getPaymentToDebtByUser(humanResource.getId());
        BigDecimal paymentToDebtResp = paymentToDebt;
        if (loanEmployeeList != null && !loanEmployeeList.isEmpty()) {
            for (LoanEmployeeView loan : loanEmployeeList) {
                BigDecimal detailPay = loan.getAmountToPay();
                if (paymentToDebtResp.compareTo(BigDecimal.ZERO) == 1) {
                    LoanEmployeeDetails loanDetail = new LoanEmployeeDetails();
                    loanDetail.setIdLoan(loan.getId());
                    loanDetail.setIdUser(loan.getIdUser());
                    loanDetail.setPaymentAmount(detailPay);
                    loanDetail.setReferenceNumber(loan.getReferenceNumber() + 1);
                    loanDetail.setCreatedOn(new Date());
                    loanDetail.setCreatedBy(getLoggedUser().getId());
                    loanDetail.setLoanEmployeeDetailStatus(ActiveStatus.ENEBLED);
                    loanDetail.setPayroll(ActiveStatus.ENEBLED);

                    humanResource.setBalance(humanResource.getBalance().subtract(detailPay));
                    LoanEmployee loanE = payrollCtrl.getLoanEmployeeById(loan.getId());
                    if(loanE.getBalance().compareTo(detailPay) < 0 || detailPay.compareTo(loanE.getBalance()) == 0){
                        paymentToDebtResp.subtract(loanE.getBalance());
                        loanDetail.setPaymentAmount(loanE.getBalance());
                        loanE.setBalance(BigDecimal.ZERO);
                    }else{
                        loanE.setBalance(loanE.getBalance().subtract(detailPay));
                        paymentToDebtResp.subtract(detailPay);
                    }
                    

                    payrollCtrl.saveLoanEmployeeDetail(loanDetail, humanResource, loanE);
                }
            }
        }
    }

    private void createEmployeeSaving(HumanResource humanResource) {
        EmployeeSaving employeeSaving = new EmployeeSaving();
        employeeSaving.setIdUser(humanResource.getId());
        employeeSaving.setEmployeeSaving(saving);
        employeeSaving.setCreatedOn(new Date());
        employeeSaving.setCreatedBy(getLoggedUser().getId());
        employeeSaving.setType(EmployeeSavingType.SAVING);
        humanResource.setEmployeeSaving(saving);
        payrollCtrl.saveEmployeeSaving(employeeSaving, humanResource);
    }
    
    private void cancelEmployeeSaving(Payroll payroll) {
        EmployeeSaving employeeSaving = new EmployeeSaving();
        employeeSaving.setIdUser(payroll.getHumanResource().getId());
        employeeSaving.setEmployeeSaving(payroll.getSaving());
        employeeSaving.setCreatedOn(new Date());
        employeeSaving.setCreatedBy(getLoggedUser().getId());
        employeeSaving.setType(EmployeeSavingType.CANCEL);
        payrollCtrl.saveEmployeeSaving(employeeSaving, payroll.getHumanResource());
    }
    
    @Override
    public void deleteRow() {
        boolean delete = true;
        delete = selectedPayroll.getActiveStatus() == ActiveStatus.ENEBLED ? true : false;
        
        

        if (delete) {
            
            List<StableGeneralBox> listGeneralBox = payrollCtrl.getStableGeneralBoxByDate(getLoggedUser().getOffice().getId(),
                    selectedPayroll.getCreatedOn(), selectedPayroll.getCreatedOn());
            if (listGeneralBox == null || listGeneralBox.isEmpty()) {
                payrollCtrl.updatePayrollByStatus(ActiveStatus.DISABLED, selectedPayroll.getId(), getLoggedUser().getUser().getId());
                
                List<LoanEmployeeDetails> loanEmployeeList = loanEmployeeController.findLoanDetailToUpdate(selectedPayroll.getHumanResource().getId(),selectedPayroll.getCreatedOn());
                
                for(LoanEmployeeDetails loanDetail: loanEmployeeList){
                
                    LoanEmployee loan = payrollCtrl.getLoanEmployeeById(loanDetail.getIdLoan());
                    
                    loan.setBalance(loan.getBalance().add(loanDetail.getPaymentAmount()));
                    loan.setLastUpdatedBy(getLoggedUser().getId());
                    loan.setLastUpdatedOn(new Date());
                    
                    
                   loanEmployeeController.updateLoanEmployee(loan);
                    
                }
                
                loanEmployeeController.updateLoanEmployeeDetailByStatus(selectedPayroll.getHumanResource().getId(),selectedPayroll.getCreatedOn());
                cancelEmployeeSaving(selectedPayroll);
                searchHistoricalAction();
   
                Bitacora bitacora = new Bitacora();
                bitacora.setAction("Eliminar nómina");
                bitacora.setCommentsUser(getComments());
                bitacora.setCreatedBy(getLoggedUser().getUser().getId());
                bitacora.setCreatedOn(new Date());
                bitacora.setNameUser(getLoggedUser().getUser().getUserName());
                bitacora.setOffice(new Office(getLoggedUser().getOffice().getId()));
                bitacora.setDescription("Se eliminó correctamente la nómina con fecha: " + selectedPayroll.getCreatedOn() + ", con monto $"
                        + selectedPayroll.getTotalPayment());
                bitacoraCtrl.saveBitacora(bitacora);
                comments = "";
                selectedPayroll = null;
                showMessage(FacesMessage.SEVERITY_INFO, "Nómina eliminada", "Se eliminó correctamente.");
            }
            else{
                showMessage(FacesMessage.SEVERITY_ERROR, "Error", "La nómina no se pudo eliminar porque existe un corte de caja general con esa fecha.");
            }
        }
    }

    public GenericController getGenericCtrl() {
        return genericCtrl;
    }

    public void setGenericCtrl(GenericController genericCtrl) {
        this.genericCtrl = genericCtrl;
    }

    public List<User> getUser() {
        return user;
    }

    public void setUser(List<User> user) {
        this.user = user;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public Date getDateInit() {
        return dateInit;
    }

    public void setDateInit(Date dateInit) {
        this.dateInit = dateInit;
    }

    public Date getDateEnd() {
        return dateEnd;
    }

    public void setDateEnd(Date dateEnd) {
        this.dateEnd = dateEnd;
    }

    public PayRollController getPayrollCtrl() {
        return payrollCtrl;
    }

    public void setPayrollCtrl(PayRollController payrollCtrl) {
        this.payrollCtrl = payrollCtrl;
    }

    public BigDecimal getSalary() {
        return salary;
    }

    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }

    public BigDecimal getImss() {
        return imss;
    }

    public void setImss(BigDecimal imss) {
        this.imss = imss;
    }

    public BigDecimal getAdvances() {
        return advances;
    }

    public void setAdvances(BigDecimal advances) {
        this.advances = advances;
    }

    public BigDecimal getNewCustomer() {
        return newCustomer;
    }

    public void setNewCustomer(BigDecimal newCustomer) {
        this.newCustomer = newCustomer;
    }

    public BigDecimal getBonusColocation() {
        return bonusColocation;
    }

    public void setBonusColocation(BigDecimal bonusColocation) {
        this.bonusColocation = bonusColocation;
    }

    public BigDecimal getBonusMora() {
        return BonusMora;
    }

    public void setBonusMora(BigDecimal BonusMora) {
        this.BonusMora = BonusMora;
    }

    public Goal getGoal() {
        return goal;
    }

    public void setGoal(Goal goal) {
        this.goal = goal;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }

    public BigDecimal getGranTotal() {
        return granTotal;
    }

    public void setGranTotal(BigDecimal granTotal) {
        this.granTotal = granTotal;
    }

    public BigDecimal getGranTotalDeducciones() {
        return granTotalDeducciones;
    }

    public void setGranTotalDeducciones(BigDecimal granTotalDeducciones) {
        this.granTotalDeducciones = granTotalDeducciones;
    }
    
    public BigDecimal getDiscounts() {
        return discounts;
    }

    public void setDiscounts(BigDecimal discounts) {
        this.discounts = discounts;
    }

    public String getCommentsDiscounts() {
        return commentsDiscounts;
    }

    public void setCommentsDiscounts(String commentsDiscounts) {
        this.commentsDiscounts = commentsDiscounts;
    }

    public BigDecimal getIncreases() {
        return increases;
    }

    public void setIncreases(BigDecimal increases) {
        this.increases = increases;
    }

    public String getCommentsIncreases() {
        return commentsIncreases;
    }

    public void setCommentsIncreases(String commentsIncreases) {
        this.commentsIncreases = commentsIncreases;
    }

    public BigDecimal getTotal() {
        return total;
    }

    public void setTotal(BigDecimal total) {
        this.total = total;
    }

    public BigDecimal getMetaInfo() {
        return metaInfo;
    }

    public void setMetaInfo(BigDecimal metaInfo) {
        this.metaInfo = metaInfo;
    }

    public BigDecimal getNewCustomerInfo() {
        return newCustomerInfo;
    }

    public void setNewCustomerInfo(BigDecimal newCustomerInfo) {
        this.newCustomerInfo = newCustomerInfo;
    }

    public BigDecimal getToalColocadoInfo() {
        return toalColocadoInfo;
    }

    public void setToalColocadoInfo(BigDecimal toalColocadoInfo) {
        this.toalColocadoInfo = toalColocadoInfo;
    }

    public BigDecimal getToalPaymentInfo() {
        return toalPaymentInfo;
    }

    public void setToalPaymentInfo(BigDecimal toalPaymentInfo) {
        this.toalPaymentInfo = toalPaymentInfo;
    }

    public BigDecimal getToalFeeInfo() {
        return toalFeeInfo;
    }

    public void setToalFeeInfo(BigDecimal toalFeeInfo) {
        this.toalFeeInfo = toalFeeInfo;
    }
    public BigDecimal getSaldoInsoluto() {
        return saldoInsoluto;
    }

    public void setSaldoInsoluto(BigDecimal saldoInsoluto) {
        this.saldoInsoluto = saldoInsoluto;
    }

    public BigDecimal getBonusNewCustomerInfo() {
        return bonusNewCustomerInfo;
    }

    public void setBonusNewCustomerInfo(BigDecimal bonusNewCustomerInfo) {
        this.bonusNewCustomerInfo = bonusNewCustomerInfo;
    }

    public BigDecimal getBonusColocationInfo() {
        return bonusColocationInfo;
    }

    public void setBonusColocationInfo(BigDecimal bonusColocationInfo) {
        this.bonusColocationInfo = bonusColocationInfo;
    }

    public BigDecimal getBonusMoraInfo() {
        return bonusMoraInfo;
    }

    public void setBonusMoraInfo(BigDecimal bonusMoraInfo) {
        this.bonusMoraInfo = bonusMoraInfo;
    }

    public String getTipoBonusInfo() {
        return tipoBonusInfo;
    }

    public void setTipoBonusInfo(String tipoBonusInfo) {
        this.tipoBonusInfo = tipoBonusInfo;
    }

    public Integer getDaysSalary() {
        return daysSalary;
    }

    public void setDaysSalary(Integer daysSalary) {
        this.daysSalary = daysSalary;
    }

    public Integer getDaysBonus() {
        return daysBonus;
    }

    public void setDaysBonus(Integer daysBonus) {
        this.daysBonus = daysBonus;
    }

    public List<Payroll> getPayroll() {
        return payroll;
    }

    public void setPayroll(List<Payroll> payroll) {
        this.payroll = payroll;
    }

    public Payroll getSelectedPayroll() {
        return selectedPayroll;
    }

    public void setSelectedPayroll(Payroll selectedPayroll) {
        this.selectedPayroll = selectedPayroll;
    }

    public DriverController getDriverCtrl() {
        return driverCtrl;
    }

    public void setDriverCtrl(DriverController driverCtrl) {
        this.driverCtrl = driverCtrl;
    }

    public List<InformationLoanLastWeekView> getData() {
        return data;
    }

    public void setData(List<InformationLoanLastWeekView> data) {
        this.data = data;
    }

    public BigDecimal getBoxed() {
        return boxed;
    }

    public void setBoxed(BigDecimal boxed) {
        this.boxed = boxed;
    }

    public BigDecimal getSaving() {
        return saving;
    }

    public void setSaving(BigDecimal saving) {
        this.saving = saving;
    }

    public BigDecimal getPaymentToDebt() {
        return paymentToDebt;
    }

    public void setPaymentToDebt(BigDecimal paymentToDebt) {
        this.paymentToDebt = paymentToDebt;
    }
    
    public GenericValidationController getGenericValidateController() {
        return genericValidateController;
    }

    public void setGenericValidateController(GenericValidationController genericController) {
        this.genericValidateController = genericController;
    }
    
    public Date getLastStableGeneralBox() {
        return lastStableGeneralBox;
    }

    public void setLastStableGeneralBox(Date lastStableGeneralBox) {
        this.lastStableGeneralBox = lastStableGeneralBox;
    }

    private GenericController genericCtrl;
    private PayRollController payrollCtrl;
    private BitacoraController bitacoraCtrl;
    private GenericValidationController genericValidateController;
    private LoanEmployeeController loanEmployeeController;

    private Date lastStableGeneralBox;
    private List<User> user;
    private List<Payroll> payroll;
    private Payroll selectedPayroll;

    private String userId;
    private Date dateInit;
    private Date dateEnd;
    private String comments;

    private BigDecimal salary;
    private BigDecimal imss;
    private BigDecimal advances;
    private BigDecimal newCustomer;
    private BigDecimal bonusColocation;
    private BigDecimal BonusMora;
    private Goal goal;
    private BigDecimal granTotal;
    private BigDecimal granTotalDeducciones;
    private BigDecimal discounts;
    private String commentsDiscounts;
    private BigDecimal increases;
    private String commentsIncreases;
    private BigDecimal total;

    private BigDecimal metaInfo;
    private BigDecimal newCustomerInfo;
    private BigDecimal toalColocadoInfo;
    private BigDecimal toalPaymentInfo;
    private BigDecimal toalFeeInfo;
    private BigDecimal saldoInsoluto;

    private BigDecimal bonusNewCustomerInfo;
    private BigDecimal bonusColocationInfo;
    private BigDecimal bonusMoraInfo;
    private String tipoBonusInfo;
    private Integer daysSalary;
    private Integer daysBonus;
    private DriverController driverCtrl;
    private List<InformationLoanLastWeekView> data;

    private BigDecimal boxed;
    private BigDecimal saving;
    private BigDecimal paymentToDebt;

    @PostConstruct
    public void init() {
        loadBundlePropertyFile();
        initOneWeekBeforeToCurrdate();

        genericCtrl = new GenericController();
        payrollCtrl = new PayRollController();
        driverCtrl = new DriverController();
        bitacoraCtrl = new BitacoraController();
        loanEmployeeController = new LoanEmployeeController();
        data = driverCtrl.getAllLoanLastWeekByOffice(getLoggedUser().getOffice().getId());
        payroll = payrollCtrl.fillPayrollDatatable(getLoggedUser().getOffice().getId(), getStarDate(), getEndDate());
        setGenericValidateController(new GenericValidationController());
        setLastStableGeneralBox(getGenericValidateController().lastStableGeneralBoxByDate(getLoggedUser().getUser()));
        user = getUsers();
        salary = BigDecimal.ZERO;
        imss = BigDecimal.ZERO;
        advances = BigDecimal.ZERO;
        newCustomer = BigDecimal.ZERO;
        bonusColocation = BigDecimal.ZERO;
        BonusMora = BigDecimal.ZERO;
        granTotal = BigDecimal.ZERO;
        granTotalDeducciones = BigDecimal.ZERO;
        total = BigDecimal.ZERO;
        discounts = BigDecimal.ZERO;
        increases = BigDecimal.ZERO;
        metaInfo = BigDecimal.ZERO;
        newCustomerInfo = BigDecimal.ZERO;
        toalColocadoInfo = BigDecimal.ZERO;
        toalPaymentInfo = BigDecimal.ZERO;
        toalFeeInfo = BigDecimal.ZERO;
        saldoInsoluto = BigDecimal.ZERO;
        bonusNewCustomerInfo = BigDecimal.ZERO;
        bonusColocationInfo = BigDecimal.ZERO;
        bonusMoraInfo = BigDecimal.ZERO;
        tipoBonusInfo = "";
        commentsDiscounts = "";
        commentsIncreases = "";
        daysBonus = 5;
        daysSalary = 5;

        boxed = BigDecimal.ZERO;
        saving = BigDecimal.ZERO;
        paymentToDebt = BigDecimal.ZERO;
        
        Calendar c = Calendar.getInstance();    
        if(c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY){
            c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            dateInit = new Date(c.getTimeInMillis());
            c.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
            dateEnd = new Date(c.getTimeInMillis());
        }
        else{
            c.add(Calendar.DAY_OF_WEEK, -7);
            c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            dateInit = new Date(c.getTimeInMillis());
            c.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
            dateEnd = new Date(c.getTimeInMillis());
        }
    }

}
