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

import com.arrebol.taxiservicios.beans.Datatable;
import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.admin.BitacoraController;
import com.arrebol.taxiservicios.controller.admin.ExpenseCompanyController;
import com.arrebol.taxiservicios.controller.admin.FeeByDriverController;
import com.arrebol.taxiservicios.controller.admin.GenericValidationController;
import com.arrebol.taxiservicios.controller.admin.SaleController;
import com.arrebol.taxiservicios.controller.catalog.BankCardController;
import com.arrebol.taxiservicios.controller.catalog.BankCardKardexController;
import com.arrebol.taxiservicios.controller.catalog.LocationController;
import com.arrebol.taxiservicios.controller.stocktaking.HistoryUpdateKmController;
import com.arrebol.taxiservicios.controller.system.SystemPropertyController;
import com.arrebol.taxiservicios.controller.system.UserController;
import com.arrebol.taxiservicios.controller.util.DateWrapper;
import com.arrebol.taxiservicios.model.admin.FeeByDriver;
import com.arrebol.taxiservicios.model.admin.Sale;
import com.arrebol.taxiservicios.model.admin.Sanction;
import com.arrebol.taxiservicios.model.admin.Taxi;
import com.arrebol.taxiservicios.model.catalog.BankCard;
import com.arrebol.taxiservicios.model.catalog.BankCardKardex;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.dashboard.ToCollect;
import com.arrebol.taxiservicios.model.enums.BankCardKardexType;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.arrebol.taxiservicios.model.enums.ExpenseStatusType;
import com.arrebol.taxiservicios.model.enums.FeeType;
import com.arrebol.taxiservicios.model.enums.SanctionType;
import com.arrebol.taxiservicios.model.enums.SystemPropertyType;
import com.arrebol.taxiservicios.model.enums.TransferType;
import com.arrebol.taxiservicios.model.stocktaking.view.HistoryUpdateKm;
import com.arrebol.taxiservicios.wrapper.SaleWrapper;
import java.io.Serializable;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.UUID;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.event.ValueChangeEvent;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.primefaces.PrimeFaces;
import org.primefaces.event.ReorderEvent;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.SlideEndEvent;
import org.primefaces.model.DefaultScheduleEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.primefaces.model.ScheduleModel;

/**
 *
 * @author oscar vargas
 */
@Named("saleAddBean")
@ViewScoped
public class SaleAddBean extends TaxiGenericBean implements Serializable, Datatable {

    public void autorizar() {
        logger.info("noPrintSale");

        try {
            boolean success = getController().autorizar(getSelectedSale().getId());

            if (success) {
                setSelectedSale(null);

                showMessage(FacesMessage.SEVERITY_INFO,
                        "Autorizar",
                        "Se autorizó correctamente");
                searchSalebyAll();
            } else {
                logger.error("Sale " + getSelectedSale() + "was not changed to no print");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        "Autorizar",
                        "No se pudo autorizar");
            }

        } catch (Exception e) {
            logger.error("autorizar: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.noprint.title"),
                    getBundlePropertyFile().getString("sale.noprint.exception.desc"));
        }

    }

    public void autorizarPending() {
        logger.info("noPrintSale");

        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
                return;
            }
            
            boolean success = getController().autorizar(getSelectedSale().getId());

            if (success) {
                
                BankCardKardex bankCardKardexObj = new BankCardKardex();

                bankCardKardexObj.setBankCard(getSelectedSale().getBankCard());
                bankCardKardexObj.setAmount(getSelectedSale().getPayDay()+getSelectedSale().getPaySaving()+getSelectedSale().getAccident());
                bankCardKardexObj.setAmountBefore(getSelectedSale().getBankCard().getBalance());
                bankCardKardexObj.setAmountAfter(bankCardKardexObj.getAmountBefore()+bankCardKardexObj.getAmount());
                bankCardKardexObj.setKardexType(BankCardKardexType.INCOME);
                bankCardKardexObj.setDescription("Pago de venta");
                bankCardKardexObj.setLocation(getSelectedSale().getTaxi().getLocation());
                
                BankCardKardexController bankCardKardexCtrl = new BankCardKardexController(); 
                bankCardKardexCtrl.save(bankCardKardexObj, getLoggedUser().getId());

                BankCard bankCard = getSelectedSale().getBankCard();
                
                bankCard.setBalance(bankCardKardexObj.getAmountAfter());
                
                BankCardController bankCardCtrl = new BankCardController();
                
                bankCardCtrl.save(bankCard, getLoggedUser().getId());
                
                
                showMessage(FacesMessage.SEVERITY_INFO,
                        "Autorizar",
                        "Se autorizó correctamente");
                searchPendingSalebyAll();
            } else {
                logger.error("Sale " + getSelectedSale() + "was not changed to no print");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        "Autorizar",
                        "No se pudo autorizar");
            }

        } catch (Exception e) {
            logger.error("autorizar: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.noprint.title"),
                    getBundlePropertyFile().getString("sale.noprint.exception.desc"));
        }

    }

    public void addScheduleSale() {
        logger.info("addScheduleSale");

        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se pueden agregar más registros porque ya existe un cuadre de caja chica del día");
                return;
            }
            if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se pueden agregar más registros porque ya existe un cuadre de caja general del día");
                return;
            }

            if (!getSaleWrapper().isTransfer() && getSaleWrapper().getCompleteTotalSale() > (getSaleWrapper().getPayDay() + getSaleWrapper().getPaySaving() + getSaleWrapper().getAccident())) {

                if (null == getSaleWrapper().getCommentsIncompleteSale() || "".equals(getSaleWrapper().getCommentsIncompleteSale().trim())) {
                    showMessage(FacesMessage.SEVERITY_WARN,
                            "Ingresa los comentarios",
                            "Venta no esta completa, por favor ingresa los comentarios");
                    return;
                }
            }
            Taxi vehicle = getController().getTaxiObject(getDriverId());
            if (getCurrentKM() == null || getCurrentKM() == 0) {

                if (vehicle != null) {

                    Calendar cal = Calendar.getInstance();
                    cal.setFirstDayOfWeek(Calendar.MONDAY);
                    cal.setMinimalDaysInFirstWeek(4);
                    cal.setTime(vehicle.getLastUpdatedOn() == null ? new Date() : vehicle.getLastUpdatedOn());
                    int weekVehicle = cal.get(Calendar.WEEK_OF_YEAR);

                    Calendar today = Calendar.getInstance();
                    today.setFirstDayOfWeek(Calendar.MONDAY);
                    today.setMinimalDaysInFirstWeek(4);
                    today.setTime(new Date());
                    int weekToday = today.get(Calendar.WEEK_OF_YEAR);

                    if (weekVehicle != weekToday) {
                        showMessage(FacesMessage.SEVERITY_WARN,
                                "Actualizar kilometraje",
                                "Debes de actualizar su kilometraje para la bitácora");
                        return;
                    }

                }
            }

            Double payment = Objects.equals(ZERO, getSaleWrapper().getPayDay()) ? ZERO : getSaleWrapper().getPayDay();
            Double saving = Objects.equals(ZERO, getSaleWrapper().getPaySaving()) ? ZERO : getSaleWrapper().getPaySaving();
            Double sinister = Objects.equals(ZERO, getSaleWrapper().getAccident()) ? ZERO : getSaleWrapper().getAccident();

            Calendar c = Calendar.getInstance();

            c.setTime(getSaleWrapper().getPayDate());

            getSale().setId(UUID.randomUUID().toString());
            getSale().setActive(false);
            getSale().setPayDate(c.getTime());
            getSale().setPayDay(payment);
            getSale().setPaySaving(saving);
            getSale().setAccident(sinister);
            getSale().setCreatedBy(new User(getLoggedUser().getId(), ""));
            getSale().setCreatedOn(DateWrapper.getTodayMXTime());
            getSale().setGarage(getSaleWrapper().isTaller());
            getSale().setNuevaAsignacion(getSaleWrapper().isNuevaAsignacion());
            getSale().setBanca(getSaleWrapper().isBanca());

            if (getSaleWrapper().isTransfer() == true) {
                getSale().setTransfer(TransferType.ENEBLED);
                getSale().setStatus(ExpenseStatusType.PENDING);
                getSale().setDescription(getSaleWrapper().getDescription());
            } else {
                getSale().setTransfer(TransferType.DISABLED);
                getSale().setStatus(ExpenseStatusType.AUTHORIZED);
                getSale().setDescription(getSaleWrapper().getCommentsIncompleteSale());
            }

            if (getController().addSale(getSale(), getLoggedUser().getId(), getDriverId(), getCurrentKM())) {

                if (null != currentKM && 0F < currentKM) {
                    HistoryUpdateKm history = new HistoryUpdateKm();
                    history.setId(UUID.randomUUID().toString());
                    history.setActiveStatus(BasicType.ENEBLED);
                    history.setComments("");
                    history.setModule("Venta");
                    history.setCreatedBy(new User(getLoggedUser().getId(), ""));
                    history.setCreatedOn(new Date());
                    history.setNewKm(getCurrentKM());
                    history.setLastKm(vehicle.getKm());
                    history.setTaxi(getSale().getTaxi());
                    getHistoryController().save(history);
                }

                setTotalVenta(getController().getTotalSaleForMonth());
                setTotalAhorro(getController().getTotalSavingForMonth());
                setTotalSiniestro(getController().getTotalAccidentForMonth());
                setTotalVentaToday(getController().getTotalSaleForToday());
                setTotalAhorroToday(getController().getTotalSavingForToday());
                setTotalSiniestroToday(getController().getTotalAccidentForToday());

                getSaleScheduleModel().addEvent(updateSaleEvent(getSale()));

                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("sale.schedule.desc"),
                        getBundlePropertyFile().getString("sale.add.success.desc"));

                setCurrentKM(0F);

                try {
                    //getController().deleteToCollectByDriverAndDate(getDriverId(), getSale().getPayDate());
                    getController().updateToCollectByTaxyDriverAndPaymentDate(getDriverId(), getSale().getPayDate(), getSaleWrapper().isTaller(), getSaleWrapper().isNuevaAsignacion(), getSaleWrapper().isBanca());
                    onDriverChange();
                } catch (Exception e) {
                    logger.error("addScheduleSale() ", e);

                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("sale.schedule.desc"),
                            getBundlePropertyFile().getString("sale.delete.to.collect.fail.desc"));
                }
            } else {
                logger.error("addScheduleSale() " + getBundlePropertyFile().getString("sale.add.fail.desc"));

                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.schedule.desc"),
                        getBundlePropertyFile().getString("sale.add.fail.desc"));
            }
        } catch (Exception e) {
            logger.error("addScheduleSale", e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.schedule.desc"),
                    getBundlePropertyFile().getString("sale.add.exception.desc"));
        }
    }

    public void deleteFeeByDriver() {
        logger.info("deleteFeeByDriver");
        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se pueden eliminar más registros porque ya existe un cuadre de caja chica del día");
                return;
            }
            if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se pueden eliminar más registros porque ya existe un cuadre de caja general del día");
                return;
            }
            if (getFeeByDriverController().updateFeeStatusById(
                    getSaleWrapper().getFeeId(),
                    FeeType.DELETED,
                    getSaleWrapper().getFeeComment(),
                    getLoggedUser(), null)) {
                onDriverChange();

                if (null == getCommentsBitacora() || getCommentsBitacora().trim().equals("")) {
                    setCommentsBitacora("El usuario " + getLoggedUser().getUserName() + " no agrego comentarios a la hora de borrar esta multa");
                }

                String actionBitacora = "Eliminar multa";
                String descBitacora = "Se eliminó la multa del chofer " + getSaleWrapper().getDriver()
                        + " con monto " + currencyFormatNumber(getSaleWrapper().getFeeAmount()) + " y fecha " + getSaleWrapper().getFeeDate();

                getBitacoraController().saveNewRecordInBitacora(createNewRecordInBitacora(UUID.randomUUID().toString(), actionBitacora, getCommentsBitacora(), descBitacora),
                        getLoggedUser().getLocation().getId());
                setCommentsBitacora("");

                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("sale.schedule.desc"),
                        getBundlePropertyFile().getString("sale.fee.delete.success.desc"));

            } else {
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.schedule.desc"),
                        getBundlePropertyFile().getString("sale.fee.delete.fail.desc"));
            }
        } catch (Exception e) {
            logger.error("deleteFeeByDriver", e);
            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.schedule.desc"),
                    getBundlePropertyFile().getString("sale.fee.delete.exception.desc"));
        } finally {
            setSaleWrapper(null);
        }
    }

    public void payFee() {
        logger.info("payFee");
        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
                return;
            }
            if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja general del día");
                return;
            }
            NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CANADA);
            String currency = nf.format(getSaleWrapper().getFeeAmount());

            Sanction sanction = new Sanction(
                    UUID.randomUUID().toString(),
                    getFeeAmount(),
                    new Date(),
                    new Person(getSaleWrapper().getDriverId()),
                    "Pago de multa del chofer " + getSaleWrapper().getDriver() + " por la cantidad de " + currency,
                    getSaleWrapper().isTransferFee() == true ? SanctionType.FEE_TRANSFER : SanctionType.FEE,
                    getLoggedUser(),
                    new Date(), getLoggedUser().getLocation(),
                    ExpenseStatusType.PENDING);

            if (getFeeByDriverController().updateFeeStatusById(
                    getSaleWrapper().getFeeId(),
                    FeeType.PAID,
                    getSaleWrapper().getFeeComment(),
                    getLoggedUser(),
                    sanction)) {

                onDriverChange();

                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("sale.schedule.desc"),
                        getBundlePropertyFile().getString("sale.fee.paid.success.desc"));
            } else {
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.schedule.desc"),
                        getBundlePropertyFile().getString("sale.fee.paid.fail.desc"));
            }
        } catch (Exception e) {
            logger.error("payFee", e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.schedule.desc"),
                    getBundlePropertyFile().getString("sale.fee.paid.exception.desc"));
        } finally {
            setSaleWrapper(null);
        }
    }

    public void addFeeByDriver() {
        logger.info("addFeeByDriver");
        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
                return;
            }
            if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja general del día");
                return;
            }
            FeeByDriver feeByDriver = new FeeByDriver(
                    UUID.randomUUID().toString(),
                    getDriver(),
                    getSaleWrapper().getFeeDate(),
                    getFeeAmount(),
                    getSaleWrapper().getFeeComment(),
                    FeeType.NO_PAID,
                    getLoggedUser(),
                    DateWrapper.getTodayMXTime());

            if (getFeeByDriverController().saveFeeByDriver(feeByDriver)) {
                onDriverChange();

                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("sale.schedule.desc"),
                        getBundlePropertyFile().getString("sale.fee.add.success.desc"));
            } else {
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.schedule.desc"),
                        getBundlePropertyFile().getString("sale.fee.add.fail.desc"));
            }
        } catch (Exception e) {
            logger.error("addFeeByDriver", e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.schedule.desc"),
                    getBundlePropertyFile().getString("sale.fee.add.exception.desc"));
        } finally {
            setSaleWrapper(null);
        }
    }

    public void updateScheduleSale() {
        logger.info("updateScheduleSale");
        try {

            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
                return;
            }
            if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja general del día");
                return;
            }
            Person person = new Person(getSaleWrapper().getDriverId());
            person.setFirstName(getSaleWrapper().getDriver());

            setSale(new Sale(getSaleWrapper().getSaleId(), person));

            Double payment = Objects.equals(ZERO, getSaleWrapper().getPayDayUpdate()) ? null : (getSaleWrapper().getPayDayUpdate() + getSaleWrapper().getPayDay());
            Double saving = Objects.equals(ZERO, getSaleWrapper().getPaySavingUpdate()) ? null : (getSaleWrapper().getPaySavingUpdate() + getSaleWrapper().getPaySaving());
            Double sinister = Objects.equals(ZERO, getSaleWrapper().getAccidentUpdate()) ? null : (getSaleWrapper().getAccidentUpdate() + getSaleWrapper().getAccident());

            getSale().setPayDay(payment);
            getSale().setPaySaving(saving);
            getSale().setAccident(sinister);
            getSale().setLastUpdatedBy(new User(getLoggedUser().getId(), ""));
            getSale().setLastUpdatedOn(DateWrapper.getTodayMXTime());

            if (getController().updateSale(getSale())) {
                setTotalVenta(getController().getTotalSaleForMonth());
                setTotalAhorro(getController().getTotalSavingForMonth());
                setTotalSiniestro(getController().getTotalAccidentForMonth());
                setTotalVentaToday(getController().getTotalSaleForToday());
                setTotalAhorroToday(getController().getTotalSavingForToday());
                setTotalSiniestroToday(getController().getTotalAccidentForToday());

                payment = Objects.equals(ZERO, getSaleWrapper().getPayDayUpdate()) ? getSaleWrapper().getPayDay() : (getSaleWrapper().getPayDayUpdate() + getSaleWrapper().getPayDay());
                saving = Objects.equals(ZERO, getSaleWrapper().getPaySavingUpdate()) ? getSaleWrapper().getPaySaving() : (getSaleWrapper().getPaySavingUpdate() + getSaleWrapper().getPaySaving());
                sinister = Objects.equals(ZERO, getSaleWrapper().getAccidentUpdate()) ? getSaleWrapper().getAccident() : (getSaleWrapper().getAccidentUpdate() + getSaleWrapper().getAccident());

                getSale().setPayDay(payment);
                getSale().setPaySaving(saving);
                getSale().setAccident(sinister);
                getSale().setPayDate(event.getStartDate());

                getSaleScheduleModel().deleteEvent(event);
                getSaleScheduleModel().addEvent(updateSaleEvent(getSale()));

                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("sale.schedule.desc"),
                        getBundlePropertyFile().getString("sale.update.success.desc"));

                try {
                    getController().deleteToCollectByDriverAndDate(getDriverId(), getSale().getPayDate());
                    onDriverChange();
                } catch (Exception e) {
                    logger.error("updateScheduleSale() ", e);

                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("sale.schedule.desc"),
                            getBundlePropertyFile().getString("sale.delete.to.collect.fail.desc"));
                }
            } else {
                logger.error("updateScheduleSale() " + getBundlePropertyFile().getString("sale.update.fail.desc"));

                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.schedule.desc"),
                        getBundlePropertyFile().getString("sale.update.fail.desc"));
            }
        } catch (Exception e) {
            logger.error("updateScheduleSale", e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.schedule.desc"),
                    getBundlePropertyFile().getString("sale.update.exception.desc"));
        }
    }

    public void onEventSelect(SelectEvent selectEvent) {
        try {
            event = (ScheduleEvent) selectEvent.getObject();
            setSaleWrapper((SaleWrapper) event.getData());

            setUnknown(false);
            setNewSale(false);
            setFee(getSaleWrapper().isFee());

            PrimeFaces current = PrimeFaces.current();

            if (!isFee()) {
                Double[] pays = getPaysByIdDriver();

                setTotal(getSaleWrapper().getPayDayUpdate() + getSaleWrapper().getPaySavingUpdate() + getSaleWrapper().getAccidentUpdate());
                setPaymentCash(ZERO);
                setChange(ZERO);

                getSaleWrapper().setPayDayUpdate(pays[0] - getSaleWrapper().getPayDay());
                getSaleWrapper().setPaySavingUpdate(pays[1] - getSaleWrapper().getPaySaving());
                getSaleWrapper().setAccidentUpdate(pays[2] - getSaleWrapper().getAccident());
                current.executeScript("PF('eventDialog').show();");
            } else {
                current.executeScript("PF('feeDialog').show();");
            }
        } catch (Exception e) {
            logger.error("onEventSelect", e);

            setUnknown(false);
            setNewSale(false);
            setFee(false);
        }
    }

    public void onDateSelect(SelectEvent selectEvent) {
        logger.info("onDateSelect");
        try {
            if (null == getDriverId() || "-1".equals(getDriverId().trim())) {
                setUnknown(true);
                setSaleWrapper(new SaleWrapper());
                setNewSale(false);
            } else {
                event = new DefaultScheduleEvent("", (Date) selectEvent.getObject(), (Date) selectEvent.getObject());

                Double[] pays = getPaysByIdDriver();

                for (Person drvr : getDrivers()) {
                    if (getDriverId().equals(drvr.getId())) {
                        setDriver(drvr);
                        break;
                    }
                }

                setUnknown(false);
                setNewSale(true);
                setSaleWrapper(new SaleWrapper(getDriver().getId(), null, pays[0], pays[1], (Date) selectEvent.getObject(), null, pays[2]));
                getSaleWrapper().setFeeDate((Date) selectEvent.getObject());
                setTotal(pays[0] + pays[1] + pays[2]);
                setPaymentCash(ZERO);
                setChange(ZERO);

                getSaleWrapper().setDriver(getDriver().getFirstName() + " "
                        + getDriver().getSecondName() + " "
                        + getDriver().getLastName() + " "
                        + getDriver().getMiddleName());

            }
        } catch (Exception e) {
            logger.error("onDateSelect", e);
            setUnknown(true);
            setSaleWrapper(new SaleWrapper());
            setNewSale(false);
            setFee(false);
        }
    }

    public void onDriverChange() {
        logger.info("fillSchelude diver: " + getDriver());
        try {
            getSaleScheduleModel().clear();

            Date startDateOnDriverChange = DateWrapper.today().subtractHours(6).subtractMonths(3).firstDateForMonth().midnigthTime().asDate();
            //Date endDateOnDriverChange = DateWrapper.today().subtractHours(6).add(Calendar.HOUR, 24).midnigthTime().asDate();
            Date endDateOnDriverChange = DateWrapper.today().addMonths(6).firstDateForMonth().subtractHours(6).add(Calendar.HOUR, 24).midnigthTime().asDate();

            //setSaleList(getController().getSalesbyDriver(getDriverId(), 
            //DateWrapper.today().subtractHours(6).subtractMonths(1).firstDateForMonth().midnigthTime().asDate(), 
            //DateWrapper.today().subtractHours(6).add(Calendar.HOUR, 24).midnigthTime().asDate()));
            setSaleList(getController().getSalesbyDriver(getDriverId(), startDateOnDriverChange, endDateOnDriverChange));

            //List<Object[]> styleDetails = getController().findStyleClassSaleByDriverIdBetweenDates(getDriverId(), 
            //DateWrapper.today().subtractHours(6).subtractMonths(1).firstDateForMonth().midnigthTime().asDate(), 
            //DateWrapper.today().subtractHours(6).add(Calendar.HOUR, 24).midnigthTime().asDate());
            List<Object[]> styleDetails = getController().findStyleClassSaleByDriverIdBetweenDates(getDriverId(), startDateOnDriverChange, endDateOnDriverChange);
            //setSaleList(getController().getSalesGroupByDriverAndPayDate(getDriverId(),DateWrapper.today().subtractHours(6).subtractMonths(1).firstDateForMonth().midnigthTime().asDate(),DateWrapper.today().subtractHours(6).add(Calendar.HOUR, 24).midnigthTime().asDate()));
            Double[] pays = getPaysByIdDriver();

            //setFees(getFeeByDriverController().findFeesBetweenDatesByDriver(
            //DateWrapper.today().subtractHours(6).subtractMonths(1).firstDateForMonth().midnigthTime().asDate(), 
            //DateWrapper.today().subtractHours(6).add(Calendar.HOUR, 24).midnigthTime().asDate(), 
            //getDriverId()));
            setFees(getFeeByDriverController().findFeesBetweenDatesByDriver(startDateOnDriverChange, endDateOnDriverChange, getDriverId()));
            setFeesPaid(getFeeByDriverController().findFeesPaidBetweenDatesByDriver(startDateOnDriverChange, endDateOnDriverChange, getDriverId()));
            for (Person drvr : getDrivers()) {
                if (getDriverId().equals(drvr.getId())) {
                    setDriver(drvr);
                    break;
                }
            }

            if (!getSaleList().isEmpty()) {
                setTaxiId(getSaleList().get(0).getTaxi().getId());
            }

            getFees().forEach((feeTmp) -> {
                DefaultScheduleEvent ev = new DefaultScheduleEvent();
                NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CANADA);
                String currency = nf.format(feeTmp.getAmount());
                SaleWrapper saleWrapperFee = new SaleWrapper(true, feeTmp.getAmount(), feeTmp.getId(), feeTmp.getComment(), feeTmp.getFeeDate());

                saleWrapperFee.setDriver(getDriver().getFirstName() + " "
                        + getDriver().getSecondName() + " "
                        + getDriver().getLastName() + " "
                        + getDriver().getMiddleName());

                saleWrapperFee.setDriverId(getDriverId());

                ev.setStyleClass(getBundlePropertyFile().getString("sale.fee.styleClass"));
                ev.setTitle("Multa " + currency);
                ev.setData(saleWrapperFee);
                ev.setStartDate(feeTmp.getFeeDate());
                ev.setEndDate(feeTmp.getFeeDate());
                ev.setAllDay(true);

                getSaleScheduleModel().addEvent(ev);
            });

            getFeesPaid().forEach((feeTmp) -> {
                DefaultScheduleEvent ev = new DefaultScheduleEvent();
                NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CANADA);
                String currency = nf.format(feeTmp.getAmount());
                SaleWrapper saleWrapperFee = new SaleWrapper(false, feeTmp.getAmount(), feeTmp.getId(), feeTmp.getComment(), feeTmp.getFeeDate());

                saleWrapperFee.setDriver(getDriver().getFirstName() + " "
                        + getDriver().getSecondName() + " "
                        + getDriver().getLastName() + " "
                        + getDriver().getMiddleName());

                saleWrapperFee.setDriverId(getDriverId());

                ev.setStyleClass(getBundlePropertyFile().getString("sale.fee.paid.styleClass"));
                ev.setTitle("Multa pagada " + currency);

                ev.setData(saleWrapperFee);
                ev.setStartDate(feeTmp.getFeeDate());
                ev.setEndDate(feeTmp.getFeeDate());
                ev.setAllDay(true);

                getSaleScheduleModel().addEvent(ev);
            });

            getSaleList().forEach((Sale s) -> {
                DefaultScheduleEvent ev = new DefaultScheduleEvent();
                SaleWrapper sw = new SaleWrapper(getDriverId(), s.getId(), s.getPayDay(), s.getPaySaving(), s.getPayDate(), s.getDescription(), s.getAccident());

                sw.setDriver(getDriver().getFirstName() + " "
                        + getDriver().getSecondName() + " "
                        + getDriver().getLastName() + " "
                        + getDriver().getMiddleName());

                if (pays[0] > s.getPayDay()
                        || pays[1] > s.getPaySaving()
                        || pays[2] > s.getAccident()) {
                    sw.setIncomplete(true);

                    double toComplete = 0;

                    if (pays[0] > s.getPayDay()) {
                        sw.setPayDayUpdate(pays[0] - s.getPayDay());
                        sw.setPayDayDisabled(false);
                        toComplete += sw.getPayDayUpdate();
                    }

                    if (pays[1] > s.getPaySaving()) {
                        sw.setPaySavingUpdate(pays[1] - s.getPaySaving());
                        sw.setPaySavingisabled(false);
                        toComplete += sw.getPaySavingUpdate();
                    }

                    if (pays[2] > s.getAccident()) {
                        sw.setAccidentUpdate(pays[2] - s.getAccident());
                        sw.setAccidentisabled(false);
                        toComplete += sw.getAccidentUpdate();
                    }

                    NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CANADA);
                    String currency = nf.format(toComplete);
                    String abonado = nf.format((sw.getPayDay() + sw.getPaySaving() + sw.getAccident()));
                    String deTotal = nf.format((pays[0] + pays[1] + pays[2]));
                    String styleClass = getBundlePropertyFile().getString("sale.incomplete.styleClass");

                    if (null != s.getGarage() && s.getGarage()) {
                        sw.setTaller(s.getGarage());
                        styleClass = getBundlePropertyFile().getString("sale.complete.styleClass");
                    }

                    ev.setStyleClass(styleClass);
                    ev.setTitle(getBundlePropertyFile().getString("sale.incomplete.title") + " " + currency);

                    Calendar saleCalendar = Calendar.getInstance();

                    saleCalendar.setTime(sw.getPayDate());
                    saleCalendar.set(Calendar.HOUR, 10);
                    saleCalendar.set(Calendar.MINUTE, 0);
                    saleCalendar.set(Calendar.SECOND, 0);
                    saleCalendar.set(Calendar.MILLISECOND, 0);

                    for (Object[] styleDetail : styleDetails) {
                        Calendar styleCalendar = Calendar.getInstance();

                        styleCalendar.setTime((Date) styleDetail[1]);
                        styleCalendar.set(Calendar.HOUR, 10);
                        styleCalendar.set(Calendar.MINUTE, 0);
                        styleCalendar.set(Calendar.SECOND, 0);
                        styleCalendar.set(Calendar.MILLISECOND, 0);

                        if (styleCalendar.equals(saleCalendar) && "schedule-payed".equals(styleDetail[0].toString())) {
                            ev.setStyleClass(getBundlePropertyFile().getString("sale.complete.styleClass"));
                            ev.setTitle("Abonó " + abonado + " de " + deTotal);
                            sw.setIncomplete(false);
                            sw.setComplete(true);
                            break;
                        }
                    }
                } else {
                    sw.setComplete(true);

                    ev.setStyleClass(getBundlePropertyFile().getString("sale.complete.styleClass"));
                    ev.setTitle(getBundlePropertyFile().getString("sale.complete.title"));
                }

                ev.setData(sw);
                ev.setStartDate(s.getPayDate());
                ev.setEndDate(s.getPayDate());
                ev.setAllDay(true);

                getSaleScheduleModel().addEvent(ev);
            });

        } catch (Exception e) {
            logger.error("fillSchelude", e);

            showMessage(FacesMessage.SEVERITY_ERROR,
                    getBundlePropertyFile().getString("sale.schedule.desc"),
                    getBundlePropertyFile().getString("sale.schedule.exception.desc"));
        }
    }

    public void prepareChange(ValueChangeEvent event) {
        logger.info("prepareChange");
        try {
            Double pay = null;
            if (event.getNewValue() instanceof Long) {
                Long tmpPay = (Long) event.getNewValue();
                pay = tmpPay.doubleValue();
            } else if (event.getNewValue() instanceof Double) {
                pay = (Double) event.getNewValue();
            }

            setPaymentCash(pay);
            logger.info("Total " + getTotal());
            logger.info("Pay with " + getPaymentCash());
            setChange(getPaymentCash() - getTotal());
            logger.info("change " + getChange());

        } catch (Exception e) {
            logger.error("prepareChange: " + e);

            showMessage(FacesMessage.SEVERITY_ERROR,
                    getBundlePropertyFile().getString("sale.payment.number.desc"),
                    getBundlePropertyFile().getString("sale.payment.number.exception.desc"));
        }
    }

    public void onInputChanged(ValueChangeEvent event) {
        logger.info("onInputChanged");
        try {
            Double pay = null;

            switch (event.getComponent().getId()) {
                case "sliderTxt":
                    Integer newValue = (Integer) event.getNewValue();

                    getSale().setPayDay(PAY_DAY * newValue);
                    getSale().setPaySaving(PAY_SAVING * newValue);
                    getSale().setAccident(PAY_ACCIDENT * newValue);
                    break;
                case "payDay":
                    pay = (Double) event.getNewValue();

                    getSale().setPayDay(pay);

                    break;
                case "paySaving":
                    pay = (Double) event.getNewValue();

                    getSale().setPaySaving(pay);

                    break;
                case "accident":
                    pay = (Double) event.getNewValue();

                    getSale().setAccident(pay);

                    break;
            }

            setTotal(getSale().getPayDay() + getSale().getPaySaving() + getSale().getAccident());
        } catch (Exception e) {
            logger.error("onInputChanged: " + e);

            showMessage(FacesMessage.SEVERITY_ERROR,
                    getBundlePropertyFile().getString("sale.payment.number.desc"),
                    getBundlePropertyFile().getString("sale.payment.number.exception.desc"));
        }
    }

    public void onInputChangedAddNewDriverEventDetails(ValueChangeEvent event) {
        logger.info("onInputChangedAddNewDriverEventDetails");
        try {
            Double pay = null;

            switch (event.getComponent().getId()) {
                case "payDay2":
                    pay = (Double) event.getNewValue();

                    getSaleWrapper().setPayDay(pay);

                    break;
                case "paySaving2":
                    pay = (Double) event.getNewValue();

                    getSaleWrapper().setPaySaving(pay);

                    break;
                case "accident2":
                    pay = (Double) event.getNewValue();

                    getSaleWrapper().setAccident(pay);

                    break;
            }

            setTotal(getSaleWrapper().getPayDay() + getSaleWrapper().getPaySaving() + getSaleWrapper().getAccident());
        } catch (Exception e) {
            logger.error("onInputChangedAddNewDriverEventDetails: " + e);

            showMessage(FacesMessage.SEVERITY_ERROR,
                    getBundlePropertyFile().getString("sale.payment.number.desc"),
                    getBundlePropertyFile().getString("sale.payment.number.exception.desc"));
        }
    }

    public void onInputChangedEventDetailsUpdate(ValueChangeEvent event) {
        logger.info("onInputChangedAddNewDriverEventDetails");
        try {
            Double pay = null;

            switch (event.getComponent().getId()) {
                case "payDay3":
                    pay = (Double) event.getNewValue();

                    getSaleWrapper().setPayDayUpdate(pay);

                    break;
                case "paySaving3":
                    pay = (Double) event.getNewValue();

                    getSaleWrapper().setPaySavingUpdate(pay);

                    break;
                case "accident3":
                    pay = (Double) event.getNewValue();

                    getSaleWrapper().setAccidentUpdate(pay);

                    break;
            }

            setTotal(getSaleWrapper().getPayDayUpdate() + getSaleWrapper().getPaySavingUpdate() + getSaleWrapper().getAccidentUpdate());
        } catch (Exception e) {
            logger.error("onInputChangedAddNewDriverEventDetails: " + e);

            showMessage(FacesMessage.SEVERITY_ERROR,
                    getBundlePropertyFile().getString("sale.payment.number.desc"),
                    getBundlePropertyFile().getString("sale.payment.number.exception.desc"));
        }
    }

    public void onSlideEnd(SlideEndEvent event) {
        logger.info("onSlideEnd");
        try {
            getSale().setPayDay(PAY_DAY * event.getValue());
            getSale().setPaySaving(PAY_SAVING * event.getValue());
            getSale().setAccident(PAY_ACCIDENT * event.getValue());

            setTotal(getSale().getPayDay() + getSale().getPaySaving() + getSale().getAccident());
        } catch (Exception e) {
            logger.error("onSlideEnd: " + e);

            showMessage(FacesMessage.SEVERITY_ERROR,
                    getBundlePropertyFile().getString("sale.payment.number.desc"),
                    getBundlePropertyFile().getString("sale.payment.number.exception.desc"));
        }
    }

    @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) {
        showMessage(FacesMessage.SEVERITY_INFO, "Registro Movido", "De columna: " + (event.getFromIndex() + 1) + " a columna: " + (event.getToIndex() + 1));
    }

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

    @Override
    public void deleteRow() {
        logger.info("deleteRow in SaleAddBean");
        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
                return;
            }
            if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja general del día");
                return;
            }
            String driverIdToAdd = getDriverIdSearch();
            Date payDateToAdd = getSelectedSale().getPayDate();

            Sale saletmp = getController().getById(getSelectedSale().getId());
            boolean success = getController().deleteSaleById(getSelectedSale().getId());

            if (success) {
                if (null == getCommentsBitacora() || getCommentsBitacora().trim().equals("")) {
                    setCommentsBitacora("El usuario " + getLoggedUser().getUserName() + " no agrego comentarios a la hora de borrar esta venta de chofer");
                }

                String actionBitacora = "Eliminar venta por chofer";
                String descBitacora = "Se eliminó la venta del chofer " + saletmp.getPerson().getFirstName() + " " + saletmp.getPerson().getLastName() + ", con el monto " + currencyFormatNumber(getSelectedSale().getPayDay())
                        + ", accidente de " + currencyFormatNumber(getSelectedSale().getAccident())
                        + ", el ahorro de " + currencyFormatNumber(getSelectedSale().getPaySaving())
                        + ", fecha de pago " + getSelectedSale().getPayDate()
                        + " y fecha de registro " + getSelectedSale().getCreatedOn();

                getBitacoraController().saveNewRecordInBitacora(createNewRecordInBitacora(UUID.randomUUID().toString(), actionBitacora, getCommentsBitacora(), descBitacora),
                        getLoggedUser().getLocation().getId());

                getSales().remove(getSelectedSale());
                setSelectedSale(null);
                setCommentsBitacora("");

                ToCollect toCollect = new ToCollect(UUID.randomUUID().toString(),
                        payDateToAdd, true, 0, new Person(driverIdToAdd),
                        new User(getLoggedUser().getId(), APP),
                        DateWrapper.today().subtractHours(6).asDate());

                success = getController().saveToCollectByDriverIdAndDate(toCollect);

                if (success) {
                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.success.desc"));
                } else {
                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.success.desc"));

                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.to.collect.fail.desc"));
                }
            } else {
                logger.error("Sale " + getSelectedSale() + "was not deleted");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.delete.title"),
                        getBundlePropertyFile().getString("sale.delete.fail.desc"));
            }

        } catch (Exception e) {
            logger.error("deleteRow: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.delete.title"),
                    getBundlePropertyFile().getString("sale.delete.exception.desc"));
        }
    }

    public void deleteRowByTaxi() {
        logger.info("deleteRowByTaxi in SaleAddBean");
        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
                return;
            }
            if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja general del día");
                return;
            }
            String driverIdToAdd = getSelectedSale().getPerson().getId();
            Date payDateToAdd = getSelectedSale().getPayDate();

            boolean success = getController().deleteSaleById(getSelectedSale().getId());

            if (success) {

                if (null == getCommentsBitacora() || getCommentsBitacora().trim().equals("")) {
                    setCommentsBitacora("El usuario " + getLoggedUser().getUserName() + " no agrego comentarios a la hora de borrar esta venta por vehículo");
                }

                String actionBitacora = "Eliminar venta por vehículo";
                String descBitacora = "Se eliminó la venta por vehículo del chofer " + getSelectedSale().getPerson().getFirstName()
                        + " " + (null == getSelectedSale().getPerson().getSecondName() ? "" : getSelectedSale().getPerson().getSecondName())
                        + " " + getSelectedSale().getPerson().getLastName()
                        + " " + (null == getSelectedSale().getPerson().getMiddleName() ? "" : getSelectedSale().getPerson().getMiddleName())
                        + " con la venta del monto " + currencyFormatNumber(getSelectedSale().getPayDay())
                        + ", accidente de " + currencyFormatNumber(getSelectedSale().getAccident())
                        + ", el ahorro de " + currencyFormatNumber(getSelectedSale().getPaySaving())
                        + ", fecha de pago " + getSelectedSale().getPayDate()
                        + " y fecha de registro " + getSelectedSale().getCreatedOn();

                getBitacoraController().saveNewRecordInBitacora(createNewRecordInBitacora(UUID.randomUUID().toString(), actionBitacora, getCommentsBitacora(), descBitacora),
                        getLoggedUser().getLocation().getId());

                getSalesTaxi().remove(getSelectedSale());
                setSelectedSale(null);
                setCommentsBitacora("");

                ToCollect toCollect = new ToCollect(UUID.randomUUID().toString(),
                        payDateToAdd, true, 0, new Person(driverIdToAdd),
                        new User(getLoggedUser().getId(), APP),
                        DateWrapper.today().subtractHours(6).asDate());

                success = getController().saveToCollectByDriverIdAndDate(toCollect);

                if (success) {
                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.success.desc"));
                } else {
                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.success.desc"));

                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.to.collect.fail.desc"));
                }
            } else {
                logger.error("Sale " + getSelectedSale() + "was not deleted");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.delete.title"),
                        getBundlePropertyFile().getString("sale.delete.fail.desc"));
            }

        } catch (Exception e) {
            logger.error("deleteRowByTaxi: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.delete.title"),
                    getBundlePropertyFile().getString("sale.delete.exception.desc"));
        }
    }

    public void deleteRowByAll() {
        logger.info("deleteRowByAll in SaleAddBean");
        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
                return;
            }
            if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja general del día");
                return;
            }
            String driverIdToAdd = getSelectedSale().getPerson().getId();
            Date payDateToAdd = getSelectedSale().getPayDate();

            boolean success = getController().deleteSaleById(getSelectedSale().getId());

            if (success) {
                if (null == getCommentsBitacora() || getCommentsBitacora().trim().equals("")) {
                    setCommentsBitacora("El usuario " + getLoggedUser().getUserName() + " no agrego comentarios a la hora de borrar esta venta general");
                }

                String actionBitacora = "Eliminar venta general";
                String descBitacora = "Se eliminó la venta general del chofer " + getSelectedSale().getPerson().getFirstName()
                        + " " + (null == getSelectedSale().getPerson().getSecondName() ? "" : getSelectedSale().getPerson().getSecondName())
                        + " " + getSelectedSale().getPerson().getLastName()
                        + " " + (null == getSelectedSale().getPerson().getMiddleName() ? "" : getSelectedSale().getPerson().getMiddleName())
                        + " con la venta del monto " + currencyFormatNumber(getSelectedSale().getPayDay())
                        + ", accidente de " + currencyFormatNumber(getSelectedSale().getAccident())
                        + ", el ahorro de " + currencyFormatNumber(getSelectedSale().getPaySaving())
                        + ", fecha de pago " + getSelectedSale().getPayDate()
                        + " y fecha de registro " + getSelectedSale().getCreatedOn();

                getBitacoraController().saveNewRecordInBitacora(createNewRecordInBitacora(UUID.randomUUID().toString(), actionBitacora, getCommentsBitacora(), descBitacora),
                        getLoggedUser().getLocation().getId());

                getSalesAll().remove(getSelectedSale());
                setSelectedSale(null);
                setCommentsBitacora("");

                ToCollect toCollect = new ToCollect(UUID.randomUUID().toString(),
                        payDateToAdd, true, 0, new Person(driverIdToAdd),
                        new User(getLoggedUser().getId(), APP),
                        DateWrapper.today().subtractHours(6).asDate());

                success = getController().saveToCollectByDriverIdAndDate(toCollect);

                if (success) {
                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.success.desc"));
                } else {
                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.success.desc"));

                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.to.collect.fail.desc"));
                }
            } else {
                logger.error("Sale " + getSelectedSale() + "was not deleted");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.delete.title"),
                        getBundlePropertyFile().getString("sale.delete.fail.desc"));
            }

        } catch (Exception e) {
            logger.error("deleteRowByAll: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.delete.title"),
                    getBundlePropertyFile().getString("sale.delete.exception.desc"));
        }
    }

    public void deleteRowByAllAuthorize() {
        logger.info("deleteRowByAll in SaleAddBean");
        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
                return;
            }
            if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja general del día");
                return;
            }
            String driverIdToAdd = getSelectedSale().getPerson().getId();
            Date payDateToAdd = getSelectedSale().getPayDate();

            boolean success = getController().deleteSaleById(getSelectedSale().getId());

            if (success) {
                if (null == getCommentsBitacora() || getCommentsBitacora().trim().equals("")) {
                    setCommentsBitacora("El usuario " + getLoggedUser().getUserName() + " no agrego comentarios a la hora de borrar esta venta general");
                }

                String actionBitacora = "Eliminar venta general";
                String descBitacora = "Se eliminó la venta general del chofer " + getSelectedSale().getPerson().getFirstName()
                        + " " + (null == getSelectedSale().getPerson().getSecondName() ? "" : getSelectedSale().getPerson().getSecondName())
                        + " " + getSelectedSale().getPerson().getLastName()
                        + " " + (null == getSelectedSale().getPerson().getMiddleName() ? "" : getSelectedSale().getPerson().getMiddleName())
                        + " con la venta del monto " + currencyFormatNumber(getSelectedSale().getPayDay())
                        + ", accidente de " + currencyFormatNumber(getSelectedSale().getAccident())
                        + ", el ahorro de " + currencyFormatNumber(getSelectedSale().getPaySaving())
                        + ", fecha de pago " + getSelectedSale().getPayDate()
                        + " y fecha de registro " + getSelectedSale().getCreatedOn();

                getBitacoraController().saveNewRecordInBitacora(createNewRecordInBitacora(UUID.randomUUID().toString(), actionBitacora, getCommentsBitacora(), descBitacora),
                        getLoggedUser().getLocation().getId());

                getSalesAllPending().remove(getSelectedSale());
                setSelectedSale(null);
                setCommentsBitacora("");

                ToCollect toCollect = new ToCollect(UUID.randomUUID().toString(),
                        payDateToAdd, true, 0, new Person(driverIdToAdd),
                        new User(getLoggedUser().getId(), APP),
                        DateWrapper.today().subtractHours(6).asDate());

                success = getController().saveToCollectByDriverIdAndDate(toCollect);

                if (success) {
                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.success.desc"));
                } else {
                    showMessage(FacesMessage.SEVERITY_INFO,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.success.desc"));

                    showMessage(FacesMessage.SEVERITY_ERROR,
                            getBundlePropertyFile().getString("sale.delete.title"),
                            getBundlePropertyFile().getString("sale.delete.to.collect.fail.desc"));
                }
            } else {
                logger.error("Sale " + getSelectedSale() + "was not deleted");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.delete.title"),
                        getBundlePropertyFile().getString("sale.delete.fail.desc"));
            }

        } catch (Exception e) {
            logger.error("deleteRowByAll: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.delete.title"),
                    getBundlePropertyFile().getString("sale.delete.exception.desc"));
        }
    }

    /**
     * Save an sale in the system.
     */
    public void addSale() {
        logger.info("addSale");
        try {
            if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Error",
                        "No se puede hacer ninguna acción si existe un corte del día");
                return;
            }
            if (getGenericController().existStableSmallBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
                return;
            }
            if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
                showMessage(FacesMessage.SEVERITY_WARN,
                        "Dia cerrado",
                        "No se puede hacer ninguna acción porque ya existe un cuadre de caja general del día");
                return;
            }
            getSale().setId(UUID.randomUUID().toString());
            getSale().setActive(false);
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.HOUR, -6);
            getSale().setCreatedOn(calendar.getTime());

            boolean success = getController().addSale(getSale(), getLoggedUser().getId(), getDriverId(), null);

            if (success) {
                Double[] pays = getPaysByIdDriver();

                setTotalVenta(getController().getTotalSaleForMonth());
                setTotalAhorro(getController().getTotalSavingForMonth());
                setTotalSiniestro(getController().getTotalAccidentForMonth());
                setTotalVentaToday(getController().getTotalSaleForToday());
                setTotalAhorroToday(getController().getTotalSavingForToday());
                setTotalSiniestroToday(getController().getTotalAccidentForToday());

                sale.setDescription("");
                sale.setId("");
                sale.setPayDay(pays[0]);
                sale.setPaySaving(pays[1]);
                sale.setAccident(pays[2]);

                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("sale.add.title"),
                        getBundlePropertyFile().getString("sale.add.success.desc"));
            } else {
                logger.error("Sale " + getSale() + " was not saved");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.add.title"),
                        getBundlePropertyFile().getString("sale.add.fail.desc"));
            }
        } catch (Exception e) {
            logger.error("addTaxi: " + e);
            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.add.title"),
                    getBundlePropertyFile().getString("sale.add.exception.desc"));
        }
    }

    /**
     * Print sale again.
     */
    public void printSale() {
        logger.info("printSale");

        try {
            boolean success = getController().printSale(getSelectedSale().getId());

            if (success) {
                setSelectedSale(null);

                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("sale.print.title"),
                        getBundlePropertyFile().getString("sale.print.success.desc"));
            } else {
                logger.error("Sale " + getSelectedSale() + "was not changed to print");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.print.title"),
                        getBundlePropertyFile().getString("sale.print.fail.desc"));
            }

        } catch (Exception e) {
            logger.error("printSale: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.print.title"),
                    getBundlePropertyFile().getString("sale.print.exception.desc"));
        }

    }

    /**
     * No Print sale.
     */
    public void noPrintSale() {
        logger.info("noPrintSale");

        try {
            boolean success = getController().noPrintSale(getSelectedSale().getId());

            if (success) {
                setSelectedSale(null);

                showMessage(FacesMessage.SEVERITY_INFO,
                        getBundlePropertyFile().getString("sale.noprint.title"),
                        getBundlePropertyFile().getString("sale.noprint.success.desc"));
            } else {
                logger.error("Sale " + getSelectedSale() + "was not changed to no print");
                showMessage(FacesMessage.SEVERITY_ERROR,
                        getBundlePropertyFile().getString("sale.noprint.title"),
                        getBundlePropertyFile().getString("sale.noprint.fail.desc"));
            }

        } catch (Exception e) {
            logger.error("noPrintSale: " + e);

            showMessage(FacesMessage.SEVERITY_FATAL,
                    getBundlePropertyFile().getString("sale.noprint.title"),
                    getBundlePropertyFile().getString("sale.noprint.exception.desc"));
        }

    }

    /**
     * Search all sales and saving by Driver.
     */
    public void searchSalebyDriver() {
        logger.info("searchSalebyDriver");

        sales = getController().getSalesbyDriver(driverIdSearch, initialDate, endDate);
        Double tempPayDay = 0.0;
        Double tempSavingDay = 0.0;
        Double tempAccident = 0.0;
        for (Sale item : sales) {
            tempPayDay = tempPayDay + item.getPayDay();
            tempSavingDay = tempSavingDay + item.getPaySaving();
            tempAccident = tempAccident + item.getAccident();
        }

        totalPay = tempPayDay;
        totalSaving = tempSavingDay;
        totalAccident = tempAccident;

    }

    public void searchSalebyUser() {
        logger.info("searchSalebyUser");

        sales = getController().getSalesbyUser(userId, initialDate, endDate);
        Double tempPayDay = 0.0;
        Double tempSavingDay = 0.0;
        Double tempAccident = 0.0;
        for (Sale item : sales) {
            tempPayDay = tempPayDay + item.getPayDay();
            tempSavingDay = tempSavingDay + item.getPaySaving();
            tempAccident = tempAccident + item.getAccident();
        }

        totalPay = tempPayDay;
        totalSaving = tempSavingDay;
        totalAccident = tempAccident;

    }

    /**
     * Search all sales and saving by Taxi.
     */
    public void searchSalebyTaxi() {
        logger.info("searchSalebyTaxi");

        salesTaxi = getController().getSalesbyTaxi(taxiIdSearch, initialDateTaxi, endDateTaxi);
        Double tempPayDay = 0.0;
        Double tempSavingDay = 0.0;
        Double tempAccident = 0.0;
        for (Sale item : salesTaxi) {
            tempPayDay = tempPayDay + item.getPayDay();
            tempSavingDay = tempSavingDay + item.getPaySaving();
            tempAccident = tempAccident + item.getAccident();
        }

        totalPayTaxi = tempPayDay;
        totalSavingTaxi = tempSavingDay;
        totalAccidentTaxi = tempAccident;

    }

    /**
     * Search all sales and saving in General.
     */
    public void searchSalebyAll() {
        logger.info("searchSalebyAll");
        List<Sale> tmp = new ArrayList<>();
        salesAll = new ArrayList<>();
        tmp = getController().getSalesAll(initialDateAll, endDateAll);
        Double tempPayDay = 0.0;
        Double tempSavingDay = 0.0;
        Double tempAccident = 0.0;
        for (Sale item : tmp) {
            if (item.getCreatedBy().getLocation().getId().equalsIgnoreCase(locationId)) {
                tempPayDay = tempPayDay + item.getPayDay();
                tempSavingDay = tempSavingDay + item.getPaySaving();
                tempAccident = tempAccident + item.getAccident();
                salesAll.add(item);
            }

        }

        totalPayByAll = tempPayDay;
        totalSavingByAll = tempSavingDay;
        totalAccidentByAll = tempAccident;

    }

    public void searchPendingSalebyAll() {
        logger.info("searchPendingSalebyAll");

        List<Sale> tmp = new ArrayList<>();
        salesAllPending = new ArrayList<>();
        tmp = getController().getSalesAllByLocationPending();

        for (Sale item : tmp) {
            if (item.getCreatedBy().getLocation().getId().equalsIgnoreCase(getLoggedUser().getLocation().getId())) {

                salesAllPending.add(item);
            }

        }
    }

    /**
     * Find for the payment that Vehicle has configuired.
     *
     * @return Position order, 0 = payDay, 1 = paySaving and 2 = payAccident.
     */
    private Double[] getPaysByIdDriver() {
        logger.info("getPaysByIdDriver");
        Double[] pays = new Double[3];
        try {
            Taxi taxi = getController().findDayPaymentsByIdDriver(getDriverId());

            if (null != taxi
                    && null != taxi.getPayDay()
                    && null != taxi.getPaySaving()
                    && null != taxi.getPayAccident()) {
                pays[0] = taxi.getPayDay();
                pays[1] = taxi.getPaySaving();
                pays[2] = taxi.getPayAccident();
            } else {
                logger.info("getPaysByIdDriver using default values");
                pays[0] = PAY_DAY;
                pays[1] = PAY_SAVING;
                pays[2] = PAY_ACCIDENT;
            }
        } catch (Exception e) {
            logger.error("getPaysByIdDriver", e);
            pays[0] = PAY_DAY;
            pays[1] = PAY_SAVING;
            pays[2] = PAY_ACCIDENT;
        }

        return pays;
    }

    /**
     * Update event.
     *
     * @param s Sale
     * @return DefaultScheduleEvent
     */
    private DefaultScheduleEvent updateSaleEvent(Sale s) {
        DefaultScheduleEvent ev = new DefaultScheduleEvent();

        try {
            SaleWrapper sw = new SaleWrapper(getDriverId(), s.getId(), s.getPayDay(), s.getPaySaving(), s.getPayDate(), s.getDescription(), s.getAccident());

            sw.setDriver(getDriver().getFirstName() + " "
                    + getDriver().getSecondName() + " "
                    + getDriver().getLastName() + " "
                    + getDriver().getMiddleName());

            Double[] pays = getPaysByIdDriver();

            /*if (PAY_DAY > s.getPayDay()
                    || PAY_SAVING > s.getPaySaving()
                    || PAY_ACCIDENT > s.getAccident()) {*/
            if (pays[0] > s.getPayDay()
                    || pays[1] > s.getPaySaving()
                    || pays[2] > s.getAccident()) {
                sw.setIncomplete(true);

                double toComplete = 0;

                if (pays[0] > s.getPayDay()) {
                    sw.setPayDayUpdate(pays[0] - s.getPayDay());
                    sw.setPayDayDisabled(false);
                    toComplete += sw.getPayDayUpdate();
                }

                if (pays[1] > s.getPaySaving()) {
                    sw.setPaySavingUpdate(pays[1] - s.getPaySaving());
                    sw.setPaySavingisabled(false);
                    toComplete += sw.getPaySavingUpdate();
                }

                if (pays[2] > s.getAccident()) {
                    sw.setAccidentUpdate(pays[2] - s.getAccident());
                    sw.setAccidentisabled(false);
                    toComplete += sw.getAccidentUpdate();
                }

                NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CANADA);
                String currency = nf.format(toComplete);

                ev.setStyleClass(getBundlePropertyFile().getString("sale.incomplete.styleClass"));
                ev.setTitle(getBundlePropertyFile().getString("sale.incomplete.title") + " " + currency);
            } else {
                sw.setComplete(true);

                ev.setStyleClass(getBundlePropertyFile().getString("sale.complete.styleClass"));
                ev.setTitle(getBundlePropertyFile().getString("sale.complete.title"));
            }

            ev.setData(sw);
            ev.setStartDate(s.getPayDate());
            ev.setEndDate(s.getPayDate());
            ev.setAllDay(true);
        } catch (Exception e) {
        }

        return ev;
    }

    @PostConstruct
    public void init() {
        logger.info("init sale");
        try {
            loadBundlePropertyFile();

            setSale(new Sale());
            setSlider(1);

            sale.setPayDay(PAY_DAY);
            sale.setDescription("");
            sale.setId("");
            sale.setPaySaving(PAY_SAVING);
            sale.setAccident(PAY_ACCIDENT);

            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.HOUR, -6);

            sale.setPayDate(calendar.getTime());

            setTotal(PAY_DAY + PAY_SAVING + PAY_ACCIDENT);
            setPaymentCash(0d);
            setChange(0d);
            setController(new SaleController());
            setLocationController(new LocationController());
            setUserController(new UserController());
            setGenericController(new GenericValidationController());
            setTotalVenta(getController().getTotalSaleForMonth());
            setTotalAhorro(getController().getTotalSavingForMonth());
            setTotalSiniestro(getController().getTotalAccidentForMonth());
            setTotalVentaToday(getController().getTotalSaleForToday());
            setTotalAhorroToday(getController().getTotalSavingForToday());
            setTotalSiniestroToday(getController().getTotalAccidentForToday());
            setTotalExpenseToday(getController().getTotalExpenseForToday());
            setTotalExpenseMonth(getController().getTotalExpenseForMonth());
            setTotalAddToday(getController().getTotalAddForToday());
            setTotalAddMonth(getController().getTotalAddForMonth());
            setSaleScheduleModel(new DefaultScheduleModel());
            setFeeByDriverController(new FeeByDriverController());
            setSystemPropertyController(new SystemPropertyController());
            setFeeAmount(new Double(getSystemPropertyController().findSystemPropertyControllerByPropertyName(SystemPropertyType.FEE).getPropertyValue()));
            setExpenseCompanyController(new ExpenseCompanyController());
            setBitacoraController(new BitacoraController());
            setHistoryController(new HistoryUpdateKmController());
            setUsers(getUserController().findUserActives(getLoggedUser().getLocation().getId()));
            setLocations(getLocationController().fillLocationDatatable());
            setLastStableSmallBox(getGenericController().lastStableSmallBoxByDate(getLoggedUser()));
            setHayCuadre(getGenericController().existStableSmallBoxByCurdate(getLoggedUser()));
            searchPendingSalebyAll();
        } catch (Exception e) {
            logger.error("init", e);
        }
    }

    private static final long serialVersionUID = 6831504475543040879L;
    private static final Double ZERO = 0.0;

    final Logger logger = LogManager.getLogger(SaleAddBean.class);

    private SaleController controller;
    private LocationController locationController;
    private GenericValidationController genericController;
    private HistoryUpdateKmController historyController;
    private UserController userController;
    private Sale sale;
    private String driverId;
    private String driverIdSearch;
    private String totalVenta;
    private String totalAhorro;
    private String totalSiniestro;
    private String totalVentaToday;
    private String totalAhorroToday;
    private String totalSiniestroToday;
    private String totalAddToday;
    private String totalAddMonth;
    private Date initialDate;
    private Date endDate;
    private List<Sale> sales;
    private List<Sale> salesTaxi;
    private List<Sale> salesAll;
    private List<Sale> salesAllPending;
    private Sale selectedSale;
    private Double totalPay;
    private Double totalSaving;
    private Double totalAccident;
    private Date initialDateTaxi;
    private Date endDateTaxi;
    private String taxiIdSearch;
    private Double totalPayTaxi;
    private Double totalSavingTaxi;
    private Double totalAccidentTaxi;
    private Double totalPayByAll;
    private Double totalSavingByAll;
    private Double totalAccidentByAll;
    private Date initialDateAll;
    private Date endDateAll;
    private String totalExpenseToday;
    private String totalExpenseMonth;
    private Integer slider;
    private static final Double PAY_DAY = 200d;
    private static final Double PAY_SAVING = 20d;
    private static final Double PAY_ACCIDENT = 10d;
    private Double total;
    private Double paymentCash;
    private Double change;
    private ScheduleModel saleScheduleModel;
    private List<Sale> saleList;
    private Person driver;
    private ScheduleEvent event = new DefaultScheduleEvent();
    private SaleWrapper saleWrapper;
    private boolean unknown;
    private boolean newSale;
    private String taxiId;
    private List<FeeByDriver> fees;
    private List<FeeByDriver> feesPaid;
    private FeeByDriverController feeByDriverController;
    private boolean fee;
    private SystemPropertyController systemPropertyController;
    private Double feeAmount;
    private ExpenseCompanyController expenseCompanyController;
    private Float currentKM;
    private BitacoraController bitacoraController;
    private String commentsBitacora;
    private String userId;
    private List<User> users;
    private String locationId;
    private List<Location> locations;
    private Date lastStableSmallBox;
    private boolean hayCuadre;

    public List<Sale> getSalesAllPending() {
        return salesAllPending;
    }

    public void setSalesAllPending(List<Sale> salesAllPending) {
        this.salesAllPending = salesAllPending;
    }

    public Date getLastStableSmallBox() {
        return lastStableSmallBox;
    }

    public void setLastStableSmallBox(Date lastStableSmallBox) {
        this.lastStableSmallBox = lastStableSmallBox;
    }

    public boolean isHayCuadre() {
        return hayCuadre;
    }

    public void setHayCuadre(boolean hayCuadre) {
        this.hayCuadre = hayCuadre;
    }

    public LocationController getLocationController() {
        return locationController;
    }

    public void setLocationController(LocationController locationController) {
        this.locationController = locationController;
    }

    public String getLocationId() {
        return locationId;
    }

    public void setLocationId(String locationId) {
        this.locationId = locationId;
    }

    public List<Location> getLocations() {
        return locations;
    }

    public void setLocations(List<Location> locations) {
        this.locations = locations;
    }

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }

    public UserController getUserController() {
        return userController;
    }

    public void setUserController(UserController userController) {
        this.userController = userController;
    }

    public String getUserId() {
        return userId;
    }

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

    public HistoryUpdateKmController getHistoryController() {
        return historyController;
    }

    public void setHistoryController(HistoryUpdateKmController historyController) {
        this.historyController = historyController;
    }

    public List<FeeByDriver> getFeesPaid() {
        return feesPaid;
    }

    public void setFeesPaid(List<FeeByDriver> feesPaid) {
        this.feesPaid = feesPaid;
    }

    public GenericValidationController getGenericController() {
        return genericController;
    }

    public void setGenericController(GenericValidationController genericController) {
        this.genericController = genericController;
    }

    public String getTotalAddToday() {
        return totalAddToday;
    }

    public void setTotalAddToday(String totalAddToday) {
        this.totalAddToday = totalAddToday;
    }

    public String getTotalAddMonth() {
        return totalAddMonth;
    }

    public void setTotalAddMonth(String totalAddMonth) {
        this.totalAddMonth = totalAddMonth;
    }

    public String getTotalExpenseMonth() {
        return totalExpenseMonth;
    }

    public void setTotalExpenseMonth(String totalExpenseMonth) {
        this.totalExpenseMonth = totalExpenseMonth;
    }

    public String getTotalExpenseToday() {
        return totalExpenseToday;
    }

    public void setTotalExpenseToday(String totalExpenseToday) {
        this.totalExpenseToday = totalExpenseToday;
    }

    public String getTotalVentaToday() {
        return totalVentaToday;
    }

    public void setTotalVentaToday(String totalVentaToday) {
        this.totalVentaToday = totalVentaToday;
    }

    public String getTotalAhorroToday() {
        return totalAhorroToday;
    }

    public void setTotalAhorroToday(String totalAhorroToday) {
        this.totalAhorroToday = totalAhorroToday;
    }

    public String getTotalSiniestroToday() {
        return totalSiniestroToday;
    }

    public void setTotalSiniestroToday(String totalSiniestroToday) {
        this.totalSiniestroToday = totalSiniestroToday;
    }

    public List<Sale> getSalesAll() {
        return salesAll;
    }

    public void setSalesAll(List<Sale> salesAll) {
        this.salesAll = salesAll;
    }

    public Date getInitialDateAll() {
        return initialDateAll;
    }

    public void setInitialDateAll(Date initialDateAll) {
        this.initialDateAll = initialDateAll;
    }

    public Date getEndDateAll() {
        return endDateAll;
    }

    public void setEndDateAll(Date endDateAll) {
        this.endDateAll = endDateAll;
    }

    public Double getTotalPayByAll() {
        return totalPayByAll;
    }

    public void setTotalPayByAll(Double totalPayByAll) {
        this.totalPayByAll = totalPayByAll;
    }

    public Double getTotalSavingByAll() {
        return totalSavingByAll;
    }

    public void setTotalSavingByAll(Double totalSavingByAll) {
        this.totalSavingByAll = totalSavingByAll;
    }

    public Double getTotalAccidentByAll() {
        return totalAccidentByAll;
    }

    public void setTotalAccidentByAll(Double totalAccidentByAll) {
        this.totalAccidentByAll = totalAccidentByAll;
    }

    public List<Sale> getSalesTaxi() {
        return salesTaxi;
    }

    public void setSalesTaxi(List<Sale> salesTaxi) {
        this.salesTaxi = salesTaxi;
    }

    public Double getTotalPayTaxi() {
        return totalPayTaxi;
    }

    public void setTotalPayTaxi(Double totalPayTaxi) {
        this.totalPayTaxi = totalPayTaxi;
    }

    public Double getTotalSavingTaxi() {
        return totalSavingTaxi;
    }

    public void setTotalSavingTaxi(Double totalSavingTaxi) {
        this.totalSavingTaxi = totalSavingTaxi;
    }

    public Double getTotalAccidentTaxi() {
        return totalAccidentTaxi;
    }

    public void setTotalAccidentTaxi(Double totalAccidentTaxi) {
        this.totalAccidentTaxi = totalAccidentTaxi;
    }

    public String getTaxiIdSearch() {
        return taxiIdSearch;
    }

    public void setTaxiIdSearch(String taxiIdSearch) {
        this.taxiIdSearch = taxiIdSearch;
    }

    public Date getInitialDateTaxi() {
        return initialDateTaxi;
    }

    public void setInitialDateTaxi(Date initialDateTaxi) {
        this.initialDateTaxi = initialDateTaxi;
    }

    public Date getEndDateTaxi() {
        return endDateTaxi;
    }

    public void setEndDateTaxi(Date endDateTaxi) {
        this.endDateTaxi = endDateTaxi;
    }

    public Double getTotalAccident() {
        return totalAccident;
    }

    public void setTotalAccident(Double totalAccident) {
        this.totalAccident = totalAccident;
    }

    public Double getTotalSaving() {
        return totalSaving;
    }

    public void setTotalSaving(Double totalSaving) {
        this.totalSaving = totalSaving;
    }

    public Double getTotalPay() {
        return totalPay;
    }

    public void setTotalPay(Double totalPay) {
        this.totalPay = totalPay;
    }

    public List<Sale> getSales() {
        return sales;
    }

    public Sale getSelectedSale() {
        return selectedSale;
    }

    public void setSelectedSale(Sale selectedSale) {
        this.selectedSale = selectedSale;
    }

    public Date getInitialDate() {
        return initialDate;
    }

    public void setInitialDate(Date initialDate) {
        this.initialDate = initialDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public String getDriverIdSearch() {
        return driverIdSearch;
    }

    public void setDriverIdSearch(String driverIdSearch) {
        this.driverIdSearch = driverIdSearch;
    }

    public String getTotalVenta() {
        return totalVenta;
    }

    public void setTotalVenta(String totalVenta) {
        this.totalVenta = totalVenta;
    }

    public void setTotalAhorro(String totalAhorro) {
        this.totalAhorro = totalAhorro;
    }

    public String getTotalAhorro() {
        return totalAhorro;
    }

    public String getDriverId() {
        return driverId;
    }

    public void setDriverId(String driverId) {
        this.driverId = driverId;
    }

    public SaleController getController() {
        return controller;
    }

    public void setController(SaleController controller) {
        this.controller = controller;
    }

    public Sale getSale() {
        return sale;
    }

    public void setSale(Sale sale) {
        this.sale = sale;
    }

    public List<Person> getAllDrivers() {
        return getController().findAllDriversThatHaveTaxi();
    }

    public List<Person> getDrivers() {
        return getController().findActiveDriversThatHaveTaxi();
    }

    public List<Taxi> getDriversWithTaxi() {
        return getController().findActiveDriversThatHaveTaxiAndTaxisDescription();
    }

    public List<Taxi> getTaxis() {
        return getController().fillTaxisComboBox();
    }

    public String getTotalSiniestro() {
        return totalSiniestro;
    }

    public void setTotalSiniestro(String totalSiniestro) {
        this.totalSiniestro = totalSiniestro;
    }

    public Integer getSlider() {
        return slider;
    }

    public void setSlider(Integer slider) {
        this.slider = slider;
    }

    public Double getTotal() {
        return total;
    }

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

    public Double getPaymentCash() {
        return paymentCash;
    }

    public void setPaymentCash(Double paymentCash) {
        try {
            this.paymentCash = paymentCash;
        } catch (Exception e) {
            logger.error(e);
        }
    }

    public Double getChange() {
        return change;
    }

    public void setChange(Double change) {
        this.change = change;
    }

    public ScheduleModel getSaleScheduleModel() {
        return saleScheduleModel;
    }

    public void setSaleScheduleModel(ScheduleModel saleScheduleModel) {
        this.saleScheduleModel = saleScheduleModel;
    }

    public List<Sale> getSaleList() {
        return saleList;
    }

    public void setSaleList(List<Sale> saleList) {
        this.saleList = saleList;
    }

    public Person getDriver() {
        return driver;
    }

    public void setDriver(Person driver) {
        this.driver = driver;
    }

    public SaleWrapper getSaleWrapper() {
        return saleWrapper;
    }

    public void setSaleWrapper(SaleWrapper saleWrapper) {
        this.saleWrapper = saleWrapper;
    }

    public boolean isUnknown() {
        return unknown;
    }

    public void setUnknown(boolean unknown) {
        this.unknown = unknown;
    }

    public boolean isNewSale() {
        return newSale;
    }

    public void setNewSale(boolean newSale) {
        this.newSale = newSale;
    }

    public String getTaxiId() {
        return taxiId;
    }

    public void setTaxiId(String taxiId) {
        this.taxiId = taxiId;
    }

    public List<FeeByDriver> getFees() {
        if (null == fees) {
            fees = new ArrayList<>();
        }
        return fees;
    }

    public void setFees(List<FeeByDriver> fees) {
        this.fees = fees;
    }

    public FeeByDriverController getFeeByDriverController() {
        return feeByDriverController;
    }

    public void setFeeByDriverController(FeeByDriverController feeByDriverController) {
        this.feeByDriverController = feeByDriverController;
    }

    public boolean isFee() {
        return fee;
    }

    public void setFee(boolean fee) {
        this.fee = fee;
    }

    public void setSystemPropertyController(SystemPropertyController systemPropertyController) {
        this.systemPropertyController = systemPropertyController;
    }

    public SystemPropertyController getSystemPropertyController() {
        return systemPropertyController;
    }

    public Double getFeeAmount() {
        return feeAmount;
    }

    public void setFeeAmount(Double feeAmount) {
        this.feeAmount = feeAmount;
    }

    public ExpenseCompanyController getExpenseCompanyController() {
        return expenseCompanyController;
    }

    public void setExpenseCompanyController(ExpenseCompanyController expenseCompanyController) {
        this.expenseCompanyController = expenseCompanyController;
    }

    public Float getCurrentKM() {
        return currentKM;
    }

    public void setCurrentKM(Float currentKM) {
        this.currentKM = currentKM;
    }

    public ScheduleEvent getEvent() {
        return event;
    }

    public void setEvent(ScheduleEvent event) {
        this.event = event;
    }

    public BitacoraController getBitacoraController() {
        return bitacoraController;
    }

    public void setBitacoraController(BitacoraController bitacoraController) {
        this.bitacoraController = bitacoraController;
    }

    public String getCommentsBitacora() {
        return commentsBitacora;
    }

    public void setCommentsBitacora(String commentsBitacora) {
        this.commentsBitacora = commentsBitacora;
    }

}
