/*
 * 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 br.com.ctecinf.nfe.view;

import br.com.ctecinf.Utils;
import br.com.ctecinf.event.SelectEvent;
import br.com.ctecinf.model.Cliente;
import br.com.ctecinf.nfe.Constants;
import br.com.ctecinf.nfe.SEFAZConnection;
import br.com.ctecinf.nfe.Cartao;
import br.com.ctecinf.nfe.NFCe;
import br.com.ctecinf.model.Produto;
import br.com.ctecinf.autocomplete.AutoCompleteField;
import br.com.ctecinf.nfe.Endereco;
import br.com.ctecinf.swing.Image;
import br.com.ctecinf.swing.OptionPane;
import br.com.ctecinf.swing.PleaseWaitDialog;
import br.com.ctecinf.table.Table;
import br.com.ctecinf.table.TableModel;
import br.com.ctecinf.text.MaskFormatter;
import br.com.ctecinf.text.NumberFormatter;
import br.com.ctecinf.view.ClienteForm;
import br.inf.portalfiscal.nfe.v400.autorizacao.TEndereco;
import br.inf.portalfiscal.nfe.v400.autorizacao.TRetEnviNFe;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URI;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

/**
 *
 * @author Cássio Conceição
 * @since 29/05/2019
 * @version 201905
 * @see http://ctecinf.com.br/
 */
public class EmissorPanel extends javax.swing.JPanel {

    private AutoCompleteField<Produto> search = null;
    private double quantidade = 1.00;

    private final AutoCompleteField<Cliente> cliente;
    private final TableModel modelTotal;
    private final Table tableProd;
    private final TableModel modelProd;

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        java.awt.Image img = Image.parse(Image.LOGO, 250).getImage();

        BufferedImage buff = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);

        Graphics2D g2d = (Graphics2D) buff.getGraphics();

        AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.35f);
        g2d.setComposite(alphaChannel);
        g2d.drawImage(img, 0, 0, null);

        g.drawImage(buff, super.getWidth() - 255, super.getHeight() - 110, null);
    }

    /**
     * Creates new form EmissorPanelV4
     */
    public EmissorPanel() {

        initComponents();

        bCliEditar.setIcon(Image.parse(Image.VIEW, 16));
        bCliEditar.setMargin(new Insets(1, 1, 1, 1));
        bCliNovo.setIcon(Image.parse(Image.EDIT, 16));
        bCliNovo.setMargin(new Insets(1, 1, 1, 1));

        bFinalizar.setIcon(Image.parse(Image.SUCCESS, 32));
        bCancelar.setIcon(Image.parse(Image.CANCEL, 32));
        bRemover.setIcon(Image.parse(Image.REMOVE, 16));

        bProdQtde.setIcon(Image.parse(Image.ADD, 16));
        bProdQtde.setMargin(new Insets(1, 1, 1, 1));

        Produto produto = new Produto();
        search = new AutoCompleteField(produto.getAutoCompleteModel());
        search.addSelectListener((SelectEvent ev) -> {
            incluirProd((Produto) ev.getValue());
        });
        search.setFont(search.getFont().deriveFont(25f));

        pSearch.setLayout(new BorderLayout());
        pSearch.add(search, BorderLayout.CENTER);

        Cliente c = new Cliente();
        cliente = new AutoCompleteField<>(c.getAutoCompleteModel());

        pCliente.setLayout(new BorderLayout());
        pCliente.add(cliente, BorderLayout.CENTER);

        modelTotal = new TableModel();
        modelTotal.addColumn("Decrição", String.class);
        modelTotal.addColumn("Valor", Double.class);
        modelTotal.addRow(new Object[]{"Sub-Total", 0.00});
        modelTotal.addRow(new Object[]{"Desconto", 0.00});
        modelTotal.addRow(new Object[]{"Total", 0.00});

        Table table = new Table(modelTotal);
        table.setPreferredScrollableViewportSize(new Dimension(150, 85));
        table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);

        pTotal.setLayout(new BorderLayout());
        pTotal.add(new JScrollPane(table));

        modelProd = new TableModel();
        modelProd.addColumn("Item", Integer.class);
        modelProd.addColumn("Cód.", Integer.class);
        modelProd.addColumn("Descrição", Produto.class);
        modelProd.addColumn("NCM", Long.class);
        modelProd.addColumn("Vlr. Unit.", BigDecimal.class);
        modelProd.addColumn("Und.", String.class);
        modelProd.addColumn("Qtde.", Double.class);
        modelProd.addColumn("Total", Double.class);
        modelProd.addColumn("Desconto", Double.class);

        tableProd = new Table(modelProd);

        pProd.setLayout(new BorderLayout());
        pProd.add(new JScrollPane(tableProd));

        pLogo.setLayout(new BorderLayout());
        pLogo.add(new JLabel(Image.parse(Image.NFCE, 150)), BorderLayout.CENTER);
    }

    private void incluirProd(Produto p) {

        Number number = OptionPane.input("Valor Unitário", p.getValorUnitario() == null ? 0.00 : p.getValorUnitario().doubleValue(), new NumberFormatter(2));

        if (number == null) {
            return;
        }

        if (number.doubleValue() == 0) {
            OptionPane.error("Valor do produto não pode ser zero.");
            return;
        }

        p.setValorUnitario(BigDecimal.valueOf(number.doubleValue()));

        p.setQuantidade(BigDecimal.valueOf(quantidade));

        double vProd = quantidade * p.getValorUnitario().doubleValue();

        Number vDesconto = OptionPane.input("Valor Total Com Desconto do Item", vProd, new NumberFormatter(2));

        Number desconto = vProd - vDesconto.doubleValue();

        double vl = (double) modelTotal.getValueAt(0, 1);
        modelTotal.setValueAt(vProd + vl, 0, 1);

        vl = (double) modelTotal.getValueAt(1, 1);
        modelTotal.setValueAt(desconto.doubleValue() + vl, 1, 1);

        double sub = (double) modelTotal.getValueAt(0, 1);
        double desc = (double) modelTotal.getValueAt(1, 1);
        double total = sub - desc;

        modelTotal.setValueAt(total, 2, 1);

        try {
            Object[] row = {modelProd.getRowCount() + 1, p.getId(), Utils.clone(p), p.getNcm().getId(), p.getValorUnitario(), p.getUndCom(), quantidade, vProd, desconto.doubleValue()};
            modelProd.addRow(row);
        } catch (IOException | ClassNotFoundException ex) {
            OptionPane.error(ex);
        }

        SwingUtilities.invokeLater(() -> {
            quantidade = 1.00;
            search.setValue(null);
            search.requestFocus();
        });
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        pSearch = new javax.swing.JPanel();
        bProdQtde = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        pCliente = new javax.swing.JPanel();
        bCliNovo = new javax.swing.JButton();
        bCliEditar = new javax.swing.JButton();
        pTotal = new javax.swing.JPanel();
        pProd = new javax.swing.JPanel();
        bFinalizar = new javax.swing.JButton();
        bRemover = new javax.swing.JButton();
        pLogo = new javax.swing.JPanel();
        bCancelar = new javax.swing.JButton();

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(null, " Produto ", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 24))); // NOI18N
        jPanel1.setOpaque(false);

        javax.swing.GroupLayout pSearchLayout = new javax.swing.GroupLayout(pSearch);
        pSearch.setLayout(pSearchLayout);
        pSearchLayout.setHorizontalGroup(
            pSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 440, Short.MAX_VALUE)
        );
        pSearchLayout.setVerticalGroup(
            pSearchLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 38, Short.MAX_VALUE)
        );

        bProdQtde.setText("Qtde.");
        bProdQtde.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bProdQtdeActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pSearch, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(bProdQtde)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(pSearch, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(bProdQtde))
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(null, " Cliente ", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 24))); // NOI18N
        jPanel2.setOpaque(false);

        javax.swing.GroupLayout pClienteLayout = new javax.swing.GroupLayout(pCliente);
        pCliente.setLayout(pClienteLayout);
        pClienteLayout.setHorizontalGroup(
            pClienteLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        pClienteLayout.setVerticalGroup(
            pClienteLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 38, Short.MAX_VALUE)
        );

        bCliNovo.setText("Adicionar Cliente");
        bCliNovo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bCliNovoActionPerformed(evt);
            }
        });

        bCliEditar.setText("Visualizar Cadastro");
        bCliEditar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bCliEditarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pCliente, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(bCliNovo)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(bCliEditar)
                        .addGap(0, 107, Short.MAX_VALUE)))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addComponent(pCliente, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(bCliNovo)
                    .addComponent(bCliEditar)))
        );

        pTotal.setBorder(javax.swing.BorderFactory.createTitledBorder(" Total NFC-e "));
        pTotal.setOpaque(false);

        javax.swing.GroupLayout pTotalLayout = new javax.swing.GroupLayout(pTotal);
        pTotal.setLayout(pTotalLayout);
        pTotalLayout.setHorizontalGroup(
            pTotalLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        pTotalLayout.setVerticalGroup(
            pTotalLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 118, Short.MAX_VALUE)
        );

        pProd.setBorder(javax.swing.BorderFactory.createTitledBorder(" Itens NFC-e "));
        pProd.setOpaque(false);

        javax.swing.GroupLayout pProdLayout = new javax.swing.GroupLayout(pProd);
        pProd.setLayout(pProdLayout);
        pProdLayout.setHorizontalGroup(
            pProdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 265, Short.MAX_VALUE)
        );
        pProdLayout.setVerticalGroup(
            pProdLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );

        bFinalizar.setText("Finalizar");
        bFinalizar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bFinalizarActionPerformed(evt);
            }
        });

        bRemover.setText("Remover Item");
        bRemover.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bRemoverActionPerformed(evt);
            }
        });

        pLogo.setOpaque(false);

        javax.swing.GroupLayout pLogoLayout = new javax.swing.GroupLayout(pLogo);
        pLogo.setLayout(pLogoLayout);
        pLogoLayout.setHorizontalGroup(
            pLogoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 153, Short.MAX_VALUE)
        );
        pLogoLayout.setVerticalGroup(
            pLogoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );

        bCancelar.setText("Cancelar");
        bCancelar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bCancelarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(bFinalizar)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(bCancelar))
                    .addComponent(pLogo, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(pTotal, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pProd, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(bRemover)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(pProd, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(bRemover)
                        .addGap(89, 89, 89))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(pTotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(bFinalizar)
                            .addComponent(bCancelar))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 32, Short.MAX_VALUE)
                        .addComponent(pLogo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void bFinalizarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bFinalizarActionPerformed

        if (modelProd.getRowCount() == 0) {
            OptionPane.alert("Adicionar produto(s) a NFC-e.");
            return;
        }

        if (cliente.getValue() == null && !OptionPane.confirm(this, "Deseja emitir NFC-e sem adicionar cliente?")) {
            OptionPane.alert("Selecione cliente e volte a finalizar.");
            return;
        }

        try {

            NFCe nfce = new NFCe();

            // Total
            double total = (double) modelTotal.getValueAt(2, 1);
            double totalPago = 0;
            modelTotal.setValueAt(total, 2, 1);

            // Cliente
            if (cliente.getValue() != null) {

                TEndereco endereco = null;

                if (total > 8000) {

                    EnderecoPanel panel = new EnderecoPanel();

                    if (OptionPane.confirm(EmissorPanel.this, panel, "Confirmar endereço")) {

                        try {

                            Endereco ender = new Endereco();
                            ender.setCEP((Number) panel.getCep().getValue());
                            ender.setCMun(panel.getMunicipio().getValue().getCodIbge());
                            ender.setNro((Number) panel.getNumero().getValue());
                            ender.setUF(panel.getMunicipio().getValue().getUfSigla().trim());
                            ender.setXBairro((String) panel.getBairro().getValue());
                            ender.setXCpl((String) panel.getComplemento().getValue());
                            ender.setXLgr((String) panel.getLogradouro().getValue());
                            ender.setXMun(panel.getMunicipio().getValue().getNome());

                            endereco = ender.getEndereco();

                        } catch (Exception ex) {
                            OptionPane.error(ex);
                            return;
                        }

                    } else {
                        OptionPane.alert("É obrigatório preenchimento do endereço do cliente com valor acima de R$ 8.000,00");
                        return;
                    }
                }

                nfce.addDest(cliente.getValue().getCpf(), cliente.getValue().getNome(), cliente.getValue().getEmail(), endereco);
            }

            // Produtos
            for (int i = 0; i < modelProd.getRowCount(); i++) {
                Produto p = (Produto) modelProd.getValueAt(i, 2);
                nfce.addProduto(p, ((Number) modelProd.getValueAt(i, 6)).doubleValue(), ((Number) modelProd.getValueAt(i, 8)).doubleValue());
            }

            // Pagamento
            do {

                String tPag = (String) OptionPane.choice("Forma de pagamento", Constants.FORMAS_PAGAMENTO);

                if (tPag == null) {
                    return;
                }

                Cartao cartao = null;

                if (tPag.equals(Constants.FORMA_PGTO_CARTAO_CRED) || tPag.equals(Constants.FORMA_PGTO_CARTAO_DEB)) {

                    cartao = OptionPane.choice("Bandeira", Cartao.CARTOES);

                    if (cartao.toString().equalsIgnoreCase("outros")) {
                        cartao.setCnpj((String) OptionPane.input("CNPJ da empresa de cartão", null, new MaskFormatter(MaskFormatter.CNPJ)));
                    }

                    cartao.setcAut((String) OptionPane.input("Número da Autorização", null, null));
                }

                Number vPag = (Number) OptionPane.input("Valor", (total - totalPago), new NumberFormatter(2));

                if (vPag == null) {
                    return;
                }

                switch (tPag) {

                    case Constants.FORMA_PGTO_DINHEIRO:
                        nfce.addPagamentoDinheiro(vPag.doubleValue());
                        break;
                    case Constants.FORMA_PGTO_CHEQUE:
                        nfce.addPagamentoCheque(vPag.doubleValue());
                        break;
                    case Constants.FORMA_PGTO_CARTAO_CRED:
                        nfce.addPagamentoCartaoCredito(cartao, vPag.doubleValue());
                        break;
                    case Constants.FORMA_PGTO_CARTAO_DEB:
                        nfce.addPagamentoCartaoDebito(cartao, vPag.doubleValue());
                        break;
                    case Constants.FORMA_PGTO_CREDIARIO:
                        nfce.addPagamentoCrediario(vPag.doubleValue());
                        break;
                    case Constants.FORMA_PGTO_DEPOSITO:
                        nfce.addPagamentoDeposito(vPag.doubleValue());
                        break;
                    case Constants.FORMA_PGTO_PIX:
                        nfce.addPagamentoPix(vPag.doubleValue());
                        break;
                    default:
                        nfce.addPagamentoOutros(vPag.doubleValue());
                        break;
                }

                totalPago += vPag.doubleValue();

            } while (totalPago < total);

            // Calcula troco
            double troco = 0.00;
            if (totalPago > total) {
                troco = totalPago - total;
            }

            // Finalizar NFC-e
            nfce.finalizar(troco);

            if (OptionPane.confirm(new ConfirmarPanel(nfce))) {
                finalizarNFCe(nfce);
            }

        } catch (Exception ex) {
            OptionPane.error(ex);
        }
    }//GEN-LAST:event_bFinalizarActionPerformed

    private void finalizarNFCe(NFCe nfce) {

        new PleaseWaitDialog() {

            @Override
            public Object exec() throws Exception {
                return SEFAZConnection.enviarNFe(nfce);
            }

            @Override
            public void end(Object result) {
                clearForm();
                if (result != null) {
                    TRetEnviNFe retEnviNFe = (TRetEnviNFe) result;
                    String msg = retEnviNFe.getProtNFe().getInfProt().getCStat() + ": " + retEnviNFe.getProtNFe().getInfProt().getXMotivo();
                    OptionPane.info(msg);
                }
            }

        }.start();
    }

    private void clearForm() {
        modelProd.removeAllRows();
        modelTotal.setValueAt(0.00, 0, 1);
        modelTotal.setValueAt(0.00, 1, 1);
        modelTotal.setValueAt(0.00, 2, 1);
        cliente.setValue(null);
        search.requestFocus();
    }

    private void bProdQtdeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bProdQtdeActionPerformed

        Number number = OptionPane.input("Quantidade", 1.00, new NumberFormatter(2));

        if (number == null) {
            return;
        }

        quantidade = number.doubleValue();
    }//GEN-LAST:event_bProdQtdeActionPerformed

    private void bCliEditarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bCliEditarActionPerformed

        if (cliente.getValue() == null) {
            OptionPane.alert("Nenhum cliente selecionado.");
        } else {
            new ClienteForm(cliente.getValue()).getFrame().setVisible(true);
        }

    }//GEN-LAST:event_bCliEditarActionPerformed

    private void bCliNovoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bCliNovoActionPerformed

        Cliente c = new Cliente();
        c.setNome(cliente.getText());

        ClienteForm form = new ClienteForm(c);
        form.getFrame().addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                if (c.getId() != null) {
                    cliente.getModel().addToSearch(c);
                    cliente.setValue(c);
                }
            }
        });
        form.getFrame().setVisible(true);

    }//GEN-LAST:event_bCliNovoActionPerformed

    private void bRemoverActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bRemoverActionPerformed

        int index = tableProd.getSelectedRow();

        if (index == -1) {
            return;
        }

        if (OptionPane.confirm("Deseja realmente excluír item [" + modelProd.getValueAt(index, 2) + "]?")) {

            double desconto = ((Number) modelProd.getValueAt(index, 8)).doubleValue();
            double total = (double) modelProd.getValueAt(index, 7);

            modelTotal.setValueAt((double) modelTotal.getValueAt(0, 1) - total, 0, 1);
            modelTotal.setValueAt((double) modelTotal.getValueAt(1, 1) - desconto, 1, 1);
            modelTotal.setValueAt((double) modelTotal.getValueAt(2, 1) - (total - desconto), 2, 1);

            try {
                tableProd.removeSelectedRow();
            } catch (Exception ex) {
            }
        }

    }//GEN-LAST:event_bRemoverActionPerformed

    private void bCancelarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bCancelarActionPerformed
        clearForm();
    }//GEN-LAST:event_bCancelarActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton bCancelar;
    private javax.swing.JButton bCliEditar;
    private javax.swing.JButton bCliNovo;
    private javax.swing.JButton bFinalizar;
    private javax.swing.JButton bProdQtde;
    private javax.swing.JButton bRemover;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel pCliente;
    private javax.swing.JPanel pLogo;
    private javax.swing.JPanel pProd;
    private javax.swing.JPanel pSearch;
    private javax.swing.JPanel pTotal;
    // End of variables declaration//GEN-END:variables
}
