/*
 * Arrebol Consultancy copyright.
 *
 * This code belongs to Arrebol Consultancy
 * its use, redistribution or modification are prohibited
 * without written authorization from Arrebol Consultancy.
 */
package com.arrebol.taxiservicios.beans.admin;

import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.admin.ClosingDayController;
import com.arrebol.taxiservicios.controller.admin.GenericValidationController;
import com.arrebol.taxiservicios.controller.system.UserController;
import com.arrebol.taxiservicios.controller.util.DateWrapper;
import com.arrebol.taxiservicios.model.admin.ClosingDay;
import com.arrebol.taxiservicios.model.admin.ClosingDayDetail;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.awt.Font;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 *
 * @author Carlos Janitzio Zavala Lopez <janitzio.zavala@arrebol.com.mx>
 */
@Named("addClosingDayBean")
@ViewScoped
public class AddClosingDayBean extends TaxiGenericBean implements Serializable {

   /**
    * On chane selected user find all totals to be set before save.
    */
   public void onChangeSelectedUser() {
      logger.info("onChangeSelectedUser");
      try {
         if (null != getSelectedUserId()) {

            findAllDetails();
         }
      } catch (Exception e) {
         logger.error(e);
         showMessage(FacesMessage.SEVERITY_ERROR,
                 getBundlePropertyFile().getString("cash.daily.cut"),
                 getBundlePropertyFile().getString("cash.daily.cut.search.exception.desc"));
      }
   }

   /**
    *
    */
   public void saveClosingDay() {
      logger.info("saveClosingDay");
      try {
         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;
         }

         // Redondeo de la cantidad a pagar y la pagada al hacer el corte
         Double totalAPagar = getTotalToPay();
         Double totalPago = getTotalPaid();
         Double totalAPagarR = Math.round(totalAPagar * 100.0) / 100.0;
         Double totalPagoR = Math.round(totalPago * 100.0) / 100.0;

         if (!(totalAPagarR.equals(totalPagoR))) {
            if (getComments() == null || getComments().isEmpty()) {
               showMessage(FacesMessage.SEVERITY_WARN,
                       "Comentarios obligatorios",
                       "Si el corte es diferente al esperado los comentarios son obligatorios");
               return;
            }

         }
         ClosingDay closingDay = new ClosingDay(UUID.randomUUID().toString());

         closingDay.setUser(new User(getSelectedUserId(), ""));
         closingDay.setActiveStatus(BasicType.ENEBLED);
         closingDay.setAmountExpected(new BigDecimal(getTotalToPay()));
         closingDay.setAmountPaid(new BigDecimal(getTotalPaid()));
         closingDay.setComments(getComments());
         closingDay.setAmountTransfer(BigDecimal.ZERO);
         closingDay.setCreatedBy(getLoggedUser());
         closingDay.setCreatedOn(DateWrapper.getTodayMXTime());
         closingDay.setLocation(new Location(getLoggedUser().getLocation().getId()));

         getDetails().stream().map(detail -> {
            detail.setId(UUID.randomUUID().toString());
            return detail;
         }).map(detail -> {
            detail.setClosingDay(closingDay);
            return detail;
         }).map(detail -> {
            detail.setCreatedBy(getLoggedUser());
            return detail;
         }).map(detail -> {
            detail.setCreatedOn(DateWrapper.getTodayMXTime());
            return detail;
         }).filter(detail -> (null == detail.getPerson() || null == detail.getPerson().getId())).forEachOrdered(detail -> {
            detail.setPerson(null);
         });

         if (getController().saveClosingDayAndDetails(closingDay, getDetails())) {
            showMessage(FacesMessage.SEVERITY_INFO, getBundlePropertyFile().getString("cash.daily.cut"), getBundlePropertyFile().getString("cash.daily.cut.add.success.desc"));

            setComments(null);
            setTotalSales(null);
            setTotalSanctionsIn(null);
            setTotalSanctionsOut(null);
            setTotalExpenses(null);
            setTotalInvoices(null);
            setTotalTransferSend(null);
            setTotalTransferReceiver(null);
            setTotalToPay(null);
            setTotalPaid(null);
            setTotalTransfer(null);
            setTotalPagosSpa(null);
            setTotalDetallesPagosSpa(null);
            setTotalDevolucionPagosVentaEntrada(null);
            setTotalDevolucionPagosVentaSalida(null);

            validateMutual = null;
            setUsers(getController().getAllActiveUsers(getLoggedUser().getLocation()));
            getDetails().clear();

            //imprimir(closingDay);
         } else {
            logger.error("saveClosingDay else error");
            showMessage(FacesMessage.SEVERITY_ERROR,
                    getBundlePropertyFile().getString("cash.daily.cut"),
                    getBundlePropertyFile().getString("cash.daily.cut.add.exception.desc"));
         }
      } catch (Exception e) {
         logger.error(e);
         showMessage(FacesMessage.SEVERITY_FATAL,
                 getBundlePropertyFile().getString("cash.daily.cut"),
                 getBundlePropertyFile().getString("cash.daily.cut.add.exception.desc"));
      }
   }

   public void imprimir(ClosingDay closingDay) {
      Document document = new Document(PageSize.LETTER);
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      try {
         PdfWriter.getInstance(document, baos);
         List<ClosingDayDetail> results = new ArrayList<>();
         results = getController().findDetailsFromClosingDayID(new ClosingDay(closingDay.getId()));
         User userTmp = getController().getUserById(closingDay.getUser().getId());
         document.open();

         DateFormat formatter = new SimpleDateFormat("dd/MM/yy");

         Paragraph printDate = new Paragraph("Fecha de impresión: " + formatter.format(new Date()), FontFactory.getFont("arial", 10, Font.BOLD, BaseColor.DARK_GRAY));
         printDate.setAlignment(Element.ALIGN_RIGHT);
         document.add(printDate);

         Paragraph title = new Paragraph("Corte del día", FontFactory.getFont("arial", 18, Font.BOLD, BaseColor.DARK_GRAY));
         title.setAlignment(Element.ALIGN_CENTER);
         document.add(title);

         String date = formatter.format(closingDay.getCreatedOn());
         document.add(new Paragraph("Fecha de creación: ", FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         document.add(new Paragraph(date, FontFactory.getFont("arial", 8, Font.PLAIN, BaseColor.BLACK)));
         document.add(new Paragraph("Asesor: ", FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         document.add(new Paragraph(userTmp.getPerson().getFirstName() + " " + userTmp.getPerson().getSecondName() + " " + userTmp.getPerson().getLastName() + " " + userTmp.getPerson().getMiddleName(), FontFactory.getFont("arial", 8, Font.PLAIN, BaseColor.BLACK)));

         document.add(new Paragraph("Monto esperado: ", FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         document.add(new Paragraph("$" + closingDay.getAmountExpected().toString(), FontFactory.getFont("arial", 8, Font.PLAIN, BaseColor.BLACK)));

         document.add(new Paragraph("Monto pagado: ", FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         document.add(new Paragraph("$" + closingDay.getAmountPaid().toString(), FontFactory.getFont("arial", 8, Font.PLAIN, BaseColor.BLACK)));

         document.add(new Paragraph("Comentarios: ", FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         document.add(new Paragraph(closingDay.getComments(), FontFactory.getFont("arial", 8, Font.PLAIN, BaseColor.BLACK)));

         document.add(Chunk.NEWLINE);

         PdfPTable table = new PdfPTable(7);
         table.setTotalWidth(new float[]{60, 60, 60, 60, 170, 60, 100});

         table.setLockedWidth(true);
         PdfPCell cell = new PdfPCell(new Paragraph("Detalles del corte",
                 FontFactory.getFont("arial", 10, Font.BOLD, BaseColor.WHITE)));

         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell.setBackgroundColor(BaseColor.BLUE);
         cell.setColspan(7);
         table.addCell(cell);

         cell = new PdfPCell(new Paragraph("Tipo",
                 FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell.setColspan(1);
         table.addCell(cell);

         cell = new PdfPCell(new Paragraph("Monto",
                 FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell.setColspan(1);
         table.addCell(cell);

         cell = new PdfPCell(new Paragraph("Ahorro",
                 FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell.setColspan(1);
         table.addCell(cell);

         cell = new PdfPCell(new Paragraph("Siniestro",
                 FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell.setColspan(1);
         table.addCell(cell);

         cell = new PdfPCell(new Paragraph("Comentarios",
                 FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell.setColspan(1);
         table.addCell(cell);

         cell = new PdfPCell(new Paragraph("Tipo",
                 FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell.setColspan(1);
         table.addCell(cell);

         cell = new PdfPCell(new Paragraph("Persona",
                 FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
         cell.setColspan(1);
         table.addCell(cell);

         for (ClosingDayDetail tmp : results) {

            cell = new PdfPCell(new Paragraph(tmp.getType(),
                    FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
            cell.setColspan(1);
            table.addCell(cell);

            cell = new PdfPCell(new Paragraph(tmp.getAmount() != null ? "$" + tmp.getAmount().toString() : "$0.00",
                    FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
            cell.setColspan(1);
            table.addCell(cell);

            cell = new PdfPCell(new Paragraph(tmp.getAmountSaving() != null ? "$" + tmp.getAmountSaving().toString() : "$0.00",
                    FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
            cell.setColspan(1);
            table.addCell(cell);

            cell = new PdfPCell(new Paragraph(tmp.getAmountAccident() != null ? "$" + tmp.getAmountAccident().toString() : "$0.00",
                    FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
            cell.setColspan(1);
            table.addCell(cell);

            cell = new PdfPCell(new Paragraph(tmp.getComments(),
                    FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
            cell.setColspan(1);
            table.addCell(cell);

            cell = new PdfPCell(new Paragraph("  ",
                    FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
            cell.setColspan(1);
            table.addCell(cell);

            cell = new PdfPCell(new Paragraph(tmp.getPerson() != null ? tmp.getPerson().getFirstName() + " " + tmp.getPerson().getSecondName() + " " + tmp.getPerson().getLastName() + " " + tmp.getPerson().getMiddleName() : "",
                    FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
            cell.setColspan(1);
            table.addCell(cell);
         }

         document.add(table);

         document.add(Chunk.NEWLINE);
         document.add(Chunk.NEWLINE);
         document.add(Chunk.NEWLINE);
         document.add(Chunk.NEWLINE);

         document.add(new Paragraph("                  __________________________                 __________________________"));
         document.add(new Paragraph("                                      Firma                                      Nombre y firma cajero responsable"));
         document.add(new Paragraph("                                " + userTmp.getPerson().getFirstName() + " " + userTmp.getPerson().getSecondName() + " " + userTmp.getPerson().getLastName() + " " + userTmp.getPerson().getMiddleName()));

      } catch (Exception e) {
         System.out.print("Error 1: " + e.getMessage());
      }

      document.close();
      FacesContext context = FacesContext.getCurrentInstance();
      Object response = context.getExternalContext().getResponse();
      if (response instanceof HttpServletResponse) {
         HttpServletResponse hrs = (HttpServletResponse) response;
         hrs.setContentType("application/pdf");
         hrs.setHeader("Content-disposition", "attachment; filename=\"corteDelDia.pdf\"");
         hrs.setContentLength(baos.size());
         try {
            ServletOutputStream out = hrs.getOutputStream();
            baos.writeTo(out);
            out.flush();

         } catch (IOException e) {
            System.out.print("Error 2: " + e.getMessage());
         }
         context.responseComplete();
      }
   }

   /**
    *
    */
   private void findAllDetails() {
      try {
         Double totalIns = 0D;

         totalIns = totalIns + (getController().findTotals(query_total_inicio_expenses, getSelectedUserId()));

         setTotalSanctionsIn(totalIns + getController().findTotals(query_total_transfer_receiver, getSelectedUserId()));
         setTotalExpenses(getController().findTotals(query_total_expenses, getSelectedUserId()) + getController().findTotals(query_total_transfer_send, getSelectedUserId()));
         setTotalPagosSpa(getController().findTotals(query_total_pagos, getSelectedUserId()));
         setTotalDetallesPagosSpa(getController().findTotals(query_total_pagos_detalle, getSelectedUserId()));
         setTotalDevolucionPagosVentaEntrada(getController().findTotals(query_total_devolucion_pago_venta_entrada, getSelectedUserId()));
         setTotalDevolucionPagosVentaSalida(getController().findTotals(query_total_devolucion_pago_venta_salida, getSelectedUserId()));

         setSaveCashDailyCut(true);
         setDetails(getController().findClosingDayDetails(getSelectedUserId()));
         sumTotals();
      } catch (Exception e) {
         logger.error(e);
         setSaveCashDailyCut(false);
         throw e;
      }
   }

   private void sumTotals() {
      try {
         totalToPay = getTotalSanctionsIn() + getTotalPagosSpa() + getTotalDetallesPagosSpa() + getTotalDevolucionPagosVentaEntrada();
         totalToPay += -(getTotalSanctionsOut() + getTotalExpenses() + getTotalDevolucionPagosVentaSalida());
         totalExpenses = getTotalExpenses() + getTotalDevolucionPagosVentaSalida();
      } catch (Exception e) {
         logger.error(e);
         setSaveCashDailyCut(false);
         throw e;
      }
   }

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

         setController(new ClosingDayController());
         setGenericController(new GenericValidationController());
         setUserController(new UserController());
         setUsers(getController().getAllActiveUsers(getLoggedUser().getLocation()));
         setSaveCashDailyCut(false);

      } catch (Exception e) {
         logger.error(e);
      }
   }

   private ClosingDayController controller;
   private GenericValidationController genericController;
   private UserController userController;
   private List<User> users;
   private String selectedUserId;
   private Double totalSales;
   private Double totalSanctionsIn;
   private Double totalSanctionsOut;
   private Double totalExpenses;
   private Double totalInvoices;
   private Double totalTransferSend;
   private Double totalTransferReceiver;
   private Double totalPaymentClient;
   private boolean saveCashDailyCut;
   private List<ClosingDayDetail> details;
   private String comments;
   private Double totalToPay;
   private Double totalPaid;
   private Double totalPagosSpa;
   private Double totalDetallesPagosSpa;
   private Double totalDevolucionPagosVentaEntrada;
   private Double totalDevolucionPagosVentaSalida;

   private Double validateMutual;
   private Double validateSale;
   private Double validateSanction;

   private Double totalTransfer;
   private boolean existSalesToPay;

   public Double getValidateSale() {
      return validateSale;
   }

   public void setValidateSale(Double validateSale) {
      this.validateSale = validateSale;
   }

   public Double getValidateSanction() {
      return validateSanction;
   }

   public void setValidateSanction(Double validateSanction) {
      this.validateSanction = validateSanction;
   }

   public GenericValidationController getGenericController() {
      return genericController;
   }

   public Double getValidateMutual() {
      return validateMutual;
   }

   public void setValidateMutual(Double validateMutual) {
      this.validateMutual = validateMutual;
   }

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

   public Double getTotalTransfer() {
      return totalTransfer;
   }

   public void setTotalTransfer(Double totalTransfer) {
      this.totalTransfer = totalTransfer;
   }

   public Double getTotalPaymentClient() {
      return totalPaymentClient;
   }

   public void setTotalPaymentClient(Double totalPaymentClient) {
      this.totalPaymentClient = totalPaymentClient;
   }

   public Double getTotalTransferSend() {
      return totalTransferSend;
   }

   public void setTotalTransferSend(Double totalTransferSend) {
      this.totalTransferSend = totalTransferSend;
   }

   public Double getTotalTransferReceiver() {
      return totalTransferReceiver;
   }

   public void setTotalTransferReceiver(Double totalTransferReceiver) {
      this.totalTransferReceiver = totalTransferReceiver;
   }

   public ClosingDayController getController() {
      return controller;
   }

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

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

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

   public String getSelectedUserId() {
      return selectedUserId;
   }

   public void setSelectedUserId(String selectedUserId) {
      this.selectedUserId = selectedUserId;
   }

   public Double getTotalSales() {
      if (null == totalSales) {
         totalSales = 0d;
      }
      return totalSales;
   }

   public void setTotalSales(Double totalSales) {
      this.totalSales = totalSales;
   }

   public Double getTotalSanctionsIn() {
      if (null == totalSanctionsIn) {
         totalSanctionsIn = 0d;
      }
      return totalSanctionsIn;
   }

   public void setTotalSanctionsIn(Double totalSanctionsIn) {
      this.totalSanctionsIn = totalSanctionsIn;
   }

   public Double getTotalSanctionsOut() {
      if (null == totalSanctionsOut) {
         totalSanctionsOut = 0d;
      }
      return totalSanctionsOut;
   }

   public void setTotalSanctionsOut(Double totalSanctionsOut) {
      this.totalSanctionsOut = totalSanctionsOut;
   }

   public Double getTotalExpenses() {
      if (null == totalExpenses) {
         totalExpenses = 0d;
      }
      return totalExpenses;
   }

   public void setTotalExpenses(Double totalExpenses) {
      this.totalExpenses = totalExpenses;
   }

   public Double getTotalInvoices() {
      if (null == totalInvoices) {
         totalInvoices = 0d;
      }
      return totalInvoices;
   }

   public void setTotalInvoices(Double totalInvoices) {
      this.totalInvoices = totalInvoices;
   }

   public boolean isSaveCashDailyCut() {
      return saveCashDailyCut;
   }

   public void setSaveCashDailyCut(boolean saveCashDailyCut) {
      this.saveCashDailyCut = saveCashDailyCut;
   }

   public List<ClosingDayDetail> getDetails() {
      return details;
   }

   public void setDetails(List<ClosingDayDetail> details) {
      this.details = details;
   }

   public String getComments() {
      return comments;
   }

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

   public Double getTotalToPay() {
      if (null == totalToPay) {
         totalToPay = 0d;
      }
      return totalToPay;
   }

   public void setTotalToPay(Double totalToPay) {
      this.totalToPay = totalToPay;
   }

   public Double getTotalPaid() {
      return totalPaid;
   }

   public void setTotalPaid(Double totalPaid) {
      if (null == totalPaid) {
         totalPaid = 0d;
      }
      this.totalPaid = totalPaid;
   }

   public boolean isExistSalesToPay() {
      return existSalesToPay;
   }

   public void setExistSalesToPay(boolean existSalesToPay) {
      this.existSalesToPay = existSalesToPay;
   }

   public UserController getUserController() {
      return userController;
   }

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

   public Double getTotalPagosSpa() {
      return totalPagosSpa;
   }

   public void setTotalPagosSpa(Double totalPagosSpa) {
      this.totalPagosSpa = totalPagosSpa;
   }

   public Double getTotalDetallesPagosSpa() {
      return totalDetallesPagosSpa;
   }

   public void setTotalDetallesPagosSpa(Double totalDetallesPagosSpa) {
      this.totalDetallesPagosSpa = totalDetallesPagosSpa;
   }

   public Double getTotalDevolucionPagosVentaEntrada() {
      return totalDevolucionPagosVentaEntrada;
   }

   public void setTotalDevolucionPagosVentaEntrada(Double totalDevolucionPagosVentaEntrada) {
      this.totalDevolucionPagosVentaEntrada = totalDevolucionPagosVentaEntrada;
   }

   public Double getTotalDevolucionPagosVentaSalida() {
      return totalDevolucionPagosVentaSalida;
   }

   public void setTotalDevolucionPagosVentaSalida(Double totalDevolucionPagosVentaSalida) {
      this.totalDevolucionPagosVentaSalida = totalDevolucionPagosVentaSalida;
   }

   final Logger logger = LogManager.getLogger(AddClosingDayBean.class);
   private static final long serialVersionUID = -2421681541992908524L;

   private final String sub_query_to_find_previously_closing_day = "(SELECT DATE(cd.created_on) FROM closing_day cd WHERE DATE(cd.created_on) <= CURDATE() AND cd.user_id = :userID AND cd.active_status = 'ENEBLED' order by cd.created_on DESC LIMIT 1)";
   private final String query_total_inicio_expenses = "SELECT IF(ISNULL(SUM(payment)),0, SUM(payment)) AS total_expenses FROM expense LEFT JOIN expense_income_catalog ON expense.id_expense_type = expense_income_catalog.id WHERE DATE(expense.created_on)  > " + sub_query_to_find_previously_closing_day + "  AND expense_status_type = 'AUTHORIZED' AND expense.created_by = :userID AND (expense_type IN ('INICIO','ABONO_FINANCIAMIENTO','PAGO_ORDEN_SERVICIO') OR (expense_income_catalog.type = 'EARNING')) ";
   private final String query_total_expenses = "SELECT IF(ISNULL(SUM(payment)),0, SUM(payment)) AS total_expenses FROM expense INNER JOIN expense_income_catalog ON expense.id_expense_type = expense_income_catalog.id WHERE DATE(expense.created_on)  > " + sub_query_to_find_previously_closing_day + "  AND expense_status_type = 'AUTHORIZED' AND expense.created_by = :userID AND expense_income_catalog.type = 'EXPENSE'";

   private final String query_total_transfer_send = "SELECT IF(ISNULL(SUM(amount_to_transfer)),0, SUM(amount_to_transfer)) AS total_transfer_send FROM transfer_car_driver WHERE DATE(created_on)  > " + sub_query_to_find_previously_closing_day + "  AND action_status = 'APPROVED' AND active_status = 'ENEBLED' AND id_user_transmitter = :userID";
   private final String query_total_transfer_receiver = "SELECT IF(ISNULL(SUM(amount_to_transfer)),0, SUM(amount_to_transfer)) AS total_transfer_receiver FROM transfer_car_driver WHERE DATE(created_on)  > " + sub_query_to_find_previously_closing_day + "  AND action_status = 'APPROVED' AND active_status = 'ENEBLED' AND id_user_receiver = :userID";

   private final String query_total_pagos = "SELECT IFNULL(SUM(pago), 0) AS total_pagos "
           + "FROM pagos WHERE DATE(fecha_pago) > " + sub_query_to_find_previously_closing_day + " "
           + " AND cobro = :userID "
           + " AND pago_estatus = 'ENABLED' "
           + " AND estatus_activo = 'ENABLED' ";

   private final String query_total_pagos_detalle = "SELECT IFNULL(SUM(pago), 0) AS total_pagos "
           + "FROM pagos_detalle WHERE DATE(created_on) > " + sub_query_to_find_previously_closing_day + " "
           + " AND created_by = :userID "
           + " AND pago_estatus = 'ENABLED' "
           + " AND estatus_activo = 'ENABLED' ";

   private final String query_total_devolucion_pago_venta_entrada = "SELECT IFNULL(SUM(cantidad_devuelta), 0) AS total "
           + "FROM devolucion_pago_venta WHERE DATE(created_on) > " + sub_query_to_find_previously_closing_day + " "
           + " AND solicitante = :userID "
           + " AND tipo_movimiento = 1 "
           + " AND pago_estatus = 'ENABLED' "
           + " AND estatus_activo = 'ENABLED' ";

   private final String query_total_devolucion_pago_venta_salida = "SELECT IFNULL(SUM(cantidad_devuelta), 0) AS total "
           + "FROM devolucion_pago_venta WHERE DATE(created_on) > " + sub_query_to_find_previously_closing_day + " "
           + " AND solicitante = :userID "
           + " AND tipo_movimiento = 0 "
           + " AND pago_estatus = 'ENABLED' "
           + " AND estatus_activo = 'ENABLED' ";

}
