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

import com.arrebol.taxiservicios.beans.admin.client.*;
import com.arrebol.taxiservicios.beans.GenericPersonBean;
import com.arrebol.taxiservicios.controller.admin.CustomerController;
import com.arrebol.taxiservicios.controller.admin.DriverController;
import com.arrebol.taxiservicios.controller.admin.ExpenseController;
import com.arrebol.taxiservicios.controller.admin.GenericValidationController;
import com.arrebol.taxiservicios.controller.admin.TaxiController;
import com.arrebol.taxiservicios.controller.sp.report.ReportCustomerPayController;
import com.arrebol.taxiservicios.model.admin.Expense;
import com.arrebol.taxiservicios.model.admin.FinancingCustomer;
import com.arrebol.taxiservicios.model.admin.Service;
import com.arrebol.taxiservicios.model.admin.Taxi;
import com.arrebol.taxiservicios.model.catalog.Location;
import com.arrebol.taxiservicios.model.core.PersonCommercialInvoice;
import com.arrebol.taxiservicios.model.enums.BasicType;
import com.arrebol.taxiservicios.model.enums.ExpenseStatusType;
import com.arrebol.taxiservicios.model.enums.ExpenseType;
import com.arrebol.taxiservicios.model.stocktaking.ServiceOrderHasProductId;
import com.arrebol.taxiservicios.model.stocktaking.view.KardexInStocktakingView;
import com.arrebol.taxiservicios.model.stocktaking.view.KardexOutStocktakingView;
import com.arrebol.taxiservicios.model.view.PersonListCustomerFinancingView;
import factura40.GenerarXML;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.security.GeneralSecurityException;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import javax.mail.MessagingException;
import javax.xml.rpc.ServiceException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import net.sf.jasperreports.engine.JRException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

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

    /**
     *
     * @param outcome
     * @return
     */
    public void updateServices() {
        logger.info("updateServices");

        setTaxi(getTaxiController().getTaxiByIdInvoice(getTaxiId()));
        setCustomerCommercialInvoice(getCustomerController().getPersonCommercialInvoiceById(getTaxi().getCustomer().getId()));
        setDetailProductOrder(getCustomerController().fillProductsDetailByOrderServicesFinancingInvoice(getTaxi().getId()));
        setDetailProductInvoice(getCustomerController().fillProductsDetailByInvoice(getTaxi().getId()));
        setExpenseToPay(getCustomerController().fillExpenseDatatableLeftJoinToFinanceInvoice(getTaxi().getId()));
        setServiceToPay(getTaxiController().findAllActiveService(getTaxi().getId()));

    }
    
    public void prepararFacturacion() {
       logger.info("prepararFacturacion");
       
        getCommercialInvoicePayMethod();
        getCommercialInvoiceType();
        getCommercialUsoCFDI();
        GenerarXML generaXml = new GenerarXML();
        try {
            int validarXml = generaXml.generadorXML(getTaxi().getCustomer(), Double.valueOf(getTotal()),
                    getCommercialInvoicePayMethod(), getLoggedUser().getLocation(),
                    getCustomerCommercialInvoice(), getCommercialInvoiceType()
                    , getSelectedServiceToPay(), getSelectedDetailProductOrderList()      
                    , getSelectedDetailProductInvoiceList(), getSelectedExpensesToPay());
        } catch (TransformerException | GeneralSecurityException | IOException ex) {
            java.util.logging.Logger.getLogger(ServiceInvoiceBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
   
    @PostConstruct
    public void init() {
        try {
            loadBundlePropertyFile();

            setController(new DriverController());
            setCustomerController(new CustomerController());
            setTaxiController(new TaxiController());
            setTaxi(null);
            totalExpense= 0.0F;
            totalPaquetes = 0.0F;
            totalProductService = 0.0F;
            totalProductInvoice = 0.0F;

            setGenericController(new GenericValidationController());
            setTaxis(getCustomerController().fillTaxisComboBoxFinance());

        } catch (Exception e) {
            logger.error("Service Invoice init", e);
        }
    }
    
    public void calculateTotalPaquetes() {

        setTotalPaquetes(getCalculatePaquete());
        setTotal(getTotalPaquetes()+getTotalExpense()+getTotalProductInvoice()+getTotalProductService());
        

    }
    
    public void calculateTotalProductService() {

        setTotalProductService(getCalculateProductService());
        setTotal(getTotalPaquetes()+getTotalExpense()+getTotalProductInvoice()+getTotalProductService());
        

    }
    
    public void calculateTotalProductInvoice() {

        setTotalProductInvoice(getCalculateProductosCompras());
        setTotal(getTotalPaquetes()+getTotalExpense()+getTotalProductInvoice()+getTotalProductService());
        

    }
    
    public void calculateTotalExpense() {

        setTotalExpense(getCalculateExpense());
        setTotal(getTotalPaquetes()+getTotalExpense()+getTotalProductInvoice()+getTotalProductService());
        

    }
    public float getCalculateProductService() {
        float zero = 0f;
        
        if (!getSelectedDetailProductOrderList().isEmpty()) {
            zero = getSelectedDetailProductOrderList()
                    .stream()
                    .map(row -> row.getPriceToPay().floatValue())
                    .reduce(zero, (accumulator, _item) -> accumulator + _item);
        }
        return zero;
    }
    
    public float getCalculatePaquete() {
        float zero = 0f;
        
        if (!getSelectedServiceToPay().isEmpty()) {
            zero = getSelectedServiceToPay()
                    .stream()
                    .map(row -> row.getCharge())
                    .reduce(zero, (accumulator, _item) -> accumulator + _item);
        }
        return zero;
    }
    
    public float getCalculateProductosCompras() {
        float zero = 0f;
        
        
        
        if (!getSelectedDetailProductInvoiceList().isEmpty()) {
            zero = getSelectedDetailProductInvoiceList()
                    .stream()
                    .map(row -> (row.getPrecioMenudeo() * row.getCantidad()))
                    .reduce(zero, (accumulator, _item) -> accumulator + _item);
        }
        
     
        return zero;
    }
    
    public float getCalculateExpense() {
        float zero = 0f;
        
       
        
        if (!getSelectedExpensesToPay().isEmpty()) {
            zero = getSelectedExpensesToPay()
                    .stream()
                    .map(row -> row.getAmountMenudeo().floatValue())
                    .reduce(zero, (accumulator, _item) -> accumulator + _item);
        }
        return zero;
    }
   
    private static final long serialVersionUID = -7284027390656669184L;

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

    private CustomerController customerController;
    private TaxiController taxiController;

    private GenericValidationController genericController;

    private float total;
    private float totalPaquetes;
    private float totalProductService;
    private float totalProductInvoice;
    private float totalExpense;
    private List<Taxi> taxis;
    private Taxi taxi;
    private PersonCommercialInvoice customerCommercialInvoice;
    private String taxiId;
    private List<KardexOutStocktakingView> detailProductOrder;
    private List<KardexOutStocktakingView> selectedDetailProductOrderList;

    private List<KardexInStocktakingView> detailProductInvoice;
    private List<KardexInStocktakingView> selectedDetailProductInvoiceList;
  
    private List<Expense> expenseToPay;
    private List<Expense> selectedExpensesToPay;
    
    private List<Service> serviceToPay;
    private List<Service> selectedServiceToPay;

    private String name;
    private String commercialInvoiceType;
    private String commercialInvoicePayMethod;
    private String commercialUsoCFDI;

    public GenericValidationController getGenericController() {
        return genericController;
    }

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

    public List<Taxi> getTaxisCombo() {
        return getCustomerController().fillTaxisComboBox();
    }

    public String getTaxiId() {
        return taxiId;
    }

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

    public List<Taxi> getTaxis() {
        return taxis;
    }

    public void setTaxis(List<Taxi> taxis) {
        this.taxis = taxis;
    }

    public CustomerController getCustomerController() {
        return customerController;
    }

    public void setCustomerController(CustomerController customerController) {
        this.customerController = customerController;
    }

    public List<KardexOutStocktakingView> getDetailProductOrder() {
        return detailProductOrder;
    }

    public void setDetailProductOrder(List<KardexOutStocktakingView> detailProductOrder) {
        this.detailProductOrder = detailProductOrder;
    }

    public List<KardexOutStocktakingView> getSelectedDetailProductOrderList() {
        return selectedDetailProductOrderList;
    }

    public void setSelectedDetailProductOrderList(List<KardexOutStocktakingView> selectedDetailProductOrderList) {
        this.selectedDetailProductOrderList = selectedDetailProductOrderList;
    }

    public List<Service> getServiceToPay() {
        return serviceToPay;
    }

    public void setServiceToPay(List<Service> serviceToPay) {
        this.serviceToPay = serviceToPay;
    }

    public List<Service> getSelectedServiceToPay() {
        return selectedServiceToPay;
    }

    public void setSelectedServiceToPay(List<Service> selectedServiceToPay) {
        this.selectedServiceToPay = selectedServiceToPay;
    }

    public TaxiController getTaxiController() {
        return taxiController;
    }

    public void setTaxiController(TaxiController taxiController) {
        this.taxiController = taxiController;
    }

    public Taxi getTaxi() {
        return taxi;
    }

    public void setTaxi(Taxi taxi) {
        this.taxi = taxi;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Expense> getExpenseToPay() {
        return expenseToPay;
    }

    public void setExpenseToPay(List<Expense> expenseToPay) {
        this.expenseToPay = expenseToPay;
    }

    public List<Expense> getSelectedExpensesToPay() {
        return selectedExpensesToPay;
    }

    public void setSelectedExpensesToPay(List<Expense> selectedExpensesToPay) {
        this.selectedExpensesToPay = selectedExpensesToPay;
    }

    public List<KardexInStocktakingView> getDetailProductInvoice() {
        return detailProductInvoice;
    }

    public void setDetailProductInvoice(List<KardexInStocktakingView> detailProductInvoice) {
        this.detailProductInvoice = detailProductInvoice;
    }

    public List<KardexInStocktakingView> getSelectedDetailProductInvoiceList() {
        return selectedDetailProductInvoiceList;
    }

    public void setSelectedDetailProductInvoiceList(List<KardexInStocktakingView> selectedDetailProductInvoiceList) {
        this.selectedDetailProductInvoiceList = selectedDetailProductInvoiceList;
    }

    public float getTotal() {
        return total;
    }

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

    public float getTotalPaquetes() {
        return totalPaquetes;
    }

    public void setTotalPaquetes(float totalPaquetes) {
        this.totalPaquetes = totalPaquetes;
    }

    public float getTotalProductService() {
        return totalProductService;
    }

    public void setTotalProductService(float totalProductService) {
        this.totalProductService = totalProductService;
    }

    public float getTotalProductInvoice() {
        return totalProductInvoice;
    }

    public void setTotalProductInvoice(float totalProductInvoice) {
        this.totalProductInvoice = totalProductInvoice;
    }

    public float getTotalExpense() {
        return totalExpense;
    }

    public void setTotalExpense(float totalExpense) {
        this.totalExpense = totalExpense;
    }

    public PersonCommercialInvoice getCustomerCommercialInvoice() {
        return customerCommercialInvoice;
    }

    public void setCustomerCommercialInvoice(PersonCommercialInvoice customerCommercialInvoice) {
        this.customerCommercialInvoice = customerCommercialInvoice;
    }

    public String getCommercialInvoiceType() {
        return commercialInvoiceType;
    }

    public void setCommercialInvoiceType(String commercialInvoiceType) {
        this.commercialInvoiceType = commercialInvoiceType;
    }

    public String getCommercialInvoicePayMethod() {
        return commercialInvoicePayMethod;
    }

    public void setCommercialInvoicePayMethod(String commercialInvoicePayMethod) {
        this.commercialInvoicePayMethod = commercialInvoicePayMethod;
    }

    public String getCommercialUsoCFDI() {
        return commercialUsoCFDI;
    }

    public void setCommercialUsoCFDI(String commercialUsoCFDI) {
        this.commercialUsoCFDI = commercialUsoCFDI;
    }
    
    
    
    
}
