Subversion Repositories Integrator Subversion

Rev

Rev 449 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

package br.com.ec.domain.model;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.commons.io.IOUtils;
import org.hibernate.annotations.ForeignKey;
import org.primefaces.model.DefaultStreamedContent;
import org.w3c.dom.Document;

import br.com.ec.core.exception.NegocioException;
import br.com.ec.core.generic.identidade.Identidade;
import br.com.ec.core.interfaces.Alterar;
import br.com.ec.core.interfaces.Cadastrar;
import br.com.ec.core.util.StringUtil;
import br.com.ec.core.util.VerificadorUtil;
import br.com.ec.domain.model.nfe.TipoModeloNotaFiscal;
import br.com.ec.domain.model.nfe.TipoNotaFiscal;
import br.com.ec.domain.model.nfe.TipoNotaFiscalNaturezaOperacao;
import br.com.ec.domain.model.nfe.TipoNotaFiscalPresencaComprador;
import br.com.ec.domain.model.nfe.TipoNotaFiscalStatusRetorno;
import br.com.ec.relatorio.util.RelatorioUtils;
import br.com.ec.web.util.DataUtil;
import nfce.TNfeProc;

@Entity
@Table(name="sec_nota_fiscal", schema="sc_sec")
public class NotaFiscal implements Serializable, Identidade {

        private static final long serialVersionUID = 1L;

        private Long sequencial;
        private String tipoModeloNotaFiscal;
        private String serie;
        private Long numeroNotaFiscal;
        private Date dataHoraEmissao;
       
        private String chave;
       
        private String tipoNotaFiscalNaturezaOperacao; // NOVO
        private String tipoNotaFiscalPresencaComprador; //NOVO
        private Boolean indicadorOperacaoConsumidorFinal;
       
        private Venda venda;
        private Pessoa pessoaEmitente;
        private Pessoa pessoaDestinatario;
        private String observacaoVenda;
//      private Transporte transporte;
        private String descricaoComplementares;
       
        private String textoXml;
        private String tipoNotaFiscal;
       
        private String protocoloAutorizacao;
        private String caminhoQrcode;
       
        private String statusRetorno;
        private String motivoRetorno;
        private Date dataHoraEvento;
        private String textoXmlEvento;
       
//      private List<NotaFiscalProduto> listaNFRemessaProdutos;
       
        private byte[] arquivoXml;
       
//      private List<Parcela> listaParcelas;
//      private List<CompraProduto> listaCompraProduto;
        private List<Lancamento> listaLancamento;
        private List<VendaFormaPagamento> listaFormaPagamento;
       
        private Boolean notaFiscalPendente;
       
        @Override
        @Transient
        public Object getId() {
                return this.getSequencial();
        }
        @Override
        public void setId(Object id) {
                this.sequencial = (Long) id;
        }
       
        @Id
        @SequenceGenerator(name = "sq_notafiscal")
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name="seq_nota_fiscal", nullable=false)
        public Long getSequencial() {
                return sequencial;
        }
        public void setSequencial(Long sequencial) {
                this.sequencial = sequencial;
        }
       
        @Column(name="dsc_serie")
        public String getSerie() {
                return serie;
        }
        public void setSerie(String serie) {
                this.serie = serie;
        }
       
        @Column(name="num_nota_fiscal", nullable=false)
        public Long getNumeroNotaFiscal() {
                return numeroNotaFiscal;
        }
        public void setNumeroNotaFiscal(Long numeroNotaFiscal) {
                this.numeroNotaFiscal = numeroNotaFiscal;
        }
       
        @Column(name="cod_nota_fiscal")
        public String getChave() {
                return chave;
        }
        public void setChave(String chave) {
                this.chave = chave;
        }
       
        @Transient
        public String getTipoNotaFiscalNaturezaOperacao() {
                return tipoNotaFiscalNaturezaOperacao;
        }
        public void setTipoNotaFiscalNaturezaOperacao(String tipoNotaFiscalNaturezaOperacao) {
                this.tipoNotaFiscalNaturezaOperacao = tipoNotaFiscalNaturezaOperacao;
        }
        @Transient
        public String descricaoTipoNotaFiscalNaturezaOperacao() {
                return VerificadorUtil.naoEstaNuloOuVazio(getTipoNotaFiscalNaturezaOperacao())? TipoNotaFiscalNaturezaOperacao.parse(getTipoNotaFiscalNaturezaOperacao()).getDescricao() : null;
        }
       
        @Transient
        public String getTipoNotaFiscalPresencaComprador() {
                return tipoNotaFiscalPresencaComprador;
        }
        public void setTipoNotaFiscalPresencaComprador(String tipoNotaFiscalPresencaComprador) {
                this.tipoNotaFiscalPresencaComprador = tipoNotaFiscalPresencaComprador;
        }
        @Transient
        public String descricaoTipoNotaFiscalPresencaComprador() {
                return VerificadorUtil.naoEstaNuloOuVazio(getTipoNotaFiscalPresencaComprador())? TipoNotaFiscalPresencaComprador.parse(getTipoNotaFiscalPresencaComprador()).getDescricao() : null;
        }
       
        @ManyToOne
        @ForeignKey(name = "fk_notafiscal_venda")
        @JoinColumn(name="seq_venda", referencedColumnName="seq_venda", insertable=true, updatable=false)
        public Venda getVenda() {
                return venda;
        }
        public void setVenda(Venda venda) {
                this.venda = venda;
        }
       
        @ManyToOne
        @ForeignKey(name = "fk_notafiscal_emitente")
        @JoinColumn(name="seq_pessoa_emitente", referencedColumnName="seq_pessoa", insertable=true, updatable=true)
        public Pessoa getPessoaEmitente() {
                return pessoaEmitente;
        }
        public void setPessoaEmitente(Pessoa pessoaEmitente) {
                this.pessoaEmitente = pessoaEmitente;
        }
       
        @ManyToOne
        @ForeignKey(name = "fk_notafiscal_destinatario")
        @JoinColumn(name="seq_pessoa_destinatario", referencedColumnName="seq_pessoa", insertable=true, updatable=true)
        public Pessoa getPessoaDestinatario() {
                return pessoaDestinatario;
        }
        public void setPessoaDestinatario(Pessoa pessoaDestinatario) {
                this.pessoaDestinatario = pessoaDestinatario;
        }
       
        @Column(name="dsc_obs_venda")
        @Size(max = 100, message = "Limite de caracteres ultrapassado: Observação da Venda")
        public String getObservacaoVenda() {
                return observacaoVenda;
        }
        public void setObservacaoVenda(String observacaoVenda) {
                this.observacaoVenda = observacaoVenda;
        }
       
        @Column(name="dsc_complementares")
        @Size(max = 1500, message = "Limite de caracteres ultrapassado: Descrição Complementares")
        public String getDescricaoComplementares() {
                return descricaoComplementares;
        }
        public void setDescricaoComplementares(String descricaoComplementares) {
                this.descricaoComplementares = descricaoComplementares;
        }

        @Column(name="dth_emissao", nullable=false)
        public Date getDataHoraEmissao() {
                return dataHoraEmissao;
        }
        public void setDataHoraEmissao(Date dataHoraEmissao) {
                this.dataHoraEmissao = dataHoraEmissao;
        }
       
        @Column(name="txt_xml")
        public String getTextoXml() {
                return textoXml;
        }
        public void setTextoXml(String textoXml) {
                this.textoXml = textoXml;
        }
       
        @Column(name="tip_nota_fiscal", nullable=false)
        @NotNull(message="Obrigatório informar o tipo da nota fiscal", groups={Cadastrar.class, Alterar.class})
        public String getTipoNotaFiscal() {
                return tipoNotaFiscal;
        }
        public void setTipoNotaFiscal(String tipoNotaFiscal) {
                this.tipoNotaFiscal = tipoNotaFiscal;
        }
        @Transient
        public String getDescricaoDoTipoNotaFiscal() {
                return VerificadorUtil.naoEstaNuloOuVazio(getTipoNotaFiscal())? TipoNotaFiscal.parse(getTipoNotaFiscal()).getDescricao() : null;
        }
       
        @Column(name="tip_modelo_notafiscal", nullable=false)
        @NotNull(message="Obrigatório informar o tipo do modelo da nota fiscal", groups={Cadastrar.class, Alterar.class})
        public String getTipoModeloNotaFiscal() {
                return tipoModeloNotaFiscal;
        }
        public void setTipoModeloNotaFiscal(String tipoModeloNotaFiscal) {
                this.tipoModeloNotaFiscal = tipoModeloNotaFiscal;
        }
        @Transient
        public String getDescricaoDoTipoModeloNotaFiscal() {
                return VerificadorUtil.naoEstaNuloOuVazio(getTipoModeloNotaFiscal())? TipoModeloNotaFiscal.parse(getTipoModeloNotaFiscal()).getDescricao() : null;
        }
       
        @Column(name="dsc_protocolo_autorizacao")
        @Size(max = 100, message = "Limite de caracteres ultrapassado: Protocolo da Autorização")
        public String getProtocoloAutorizacao() {
                return protocoloAutorizacao;
        }
        public void setProtocoloAutorizacao(String protocoloAutorizacao) {
                this.protocoloAutorizacao = protocoloAutorizacao;
        }

        @Column(name="dsc_caminho_qrcode")
        @Size(max = 500, message = "Limite de caracteres ultrapassado: Caminho QRCode")
        public String getCaminhoQrcode() {
                return caminhoQrcode;
        }
        public void setCaminhoQrcode(String caminhoQrcode) {
                this.caminhoQrcode = caminhoQrcode;
        }
       
        @Column(name="dsc_status_retorno")
        @Size(max = 100, message = "Limite de caracteres ultrapassado: Status do Retorno")
        public String getStatusRetorno() {
                return statusRetorno;
        }
        public void setStatusRetorno(String statusRetorno) {
                this.statusRetorno = statusRetorno;
        }
        @Transient
        public String resultadoStatusRetorno() {
                TipoNotaFiscalStatusRetorno tipoStatus = TipoNotaFiscalStatusRetorno.parse(new Long(getStatusRetorno()));
                return VerificadorUtil.naoEstaNulo(tipoStatus)? tipoStatus.getDescricao() : getStatusRetorno();
        }
       
        @Column(name="dsc_motivo_retorno")
        @Size(max = 100, message = "Limite de caracteres ultrapassado: Motivo do Retorno")
        public String getMotivoRetorno() {
                return motivoRetorno;
        }
        public void setMotivoRetorno(String motivoRetorno) {
                this.motivoRetorno = motivoRetorno;
        }
       
        @Column(name="dth_evento")
        public Date getDataHoraEvento() {
                return dataHoraEvento;
        }
        public void setDataHoraEvento(Date dataHoraEvento) {
                this.dataHoraEvento = dataHoraEvento;
        }
       
        @Column(name="txt_xml_evento", nullable=false)
        public String getTextoXmlEvento() {
                return textoXmlEvento;
        }
        public void setTextoXmlEvento(String textoXmlEvento) {
                this.textoXmlEvento = textoXmlEvento;
        }
       
//      @OneToMany(mappedBy="notaFiscal", cascade=CascadeType.ALL, orphanRemoval=true)
        /*
        @Transient
        public List<NotaFiscalProduto> getListaNFRemessaProdutos() {
                return listaNFRemessaProdutos;
        }
        public void setListaNFRemessaProdutos(List<NotaFiscalProduto> listaNFRemessaProdutos) {
                this.listaNFRemessaProdutos = listaNFRemessaProdutos;
        }
        */

       
        @Transient
        public Boolean temPessoaJuridica() {
                if (VerificadorUtil.estaNulo(getVenda())) return false;
                if (VerificadorUtil.estaNulo(getVenda().getLoja())) return false;
                return VerificadorUtil.naoEstaNulo(getVenda().getLoja().getPessoaJuridica());
        }
       
        @Transient
        public String getRazaoSocialDaLoja() {
                return temPessoaJuridica()? getVenda().getLoja().getPessoaJuridica().getRazaoSocial() : "";
        }
       
        @Transient
        public String getCnpjDaLoja() {
                return temPessoaJuridica()? StringUtil.formatarCnpj(getVenda().getLoja().getPessoaJuridica().getCpfCnpj()) : "";
        }
       
        @Transient
        public byte[] getArquivoXml() {
                return arquivoXml;
        }
        public void setArquivoXml(byte[] arquivoXml) {
                this.arquivoXml = arquivoXml;
        }
       
        /*
        @Transient
        public List<Parcela> getListaParcelas() {
                return listaParcelas;
        }
        public void setListaParcelas(List<Parcela> listaParcelas) {
                this.listaParcelas = listaParcelas;
        }
        */

       
        /*
        @Transient
        public List<CompraProduto> getListaCompraProduto() {
                return listaCompraProduto;
        }
        public void setListaCompraProduto(List<CompraProduto> listaCompraProduto) {
                this.listaCompraProduto = listaCompraProduto;
        }
        */

       
        @Transient
        public List<Lancamento> getListaLancamento() {
                return listaLancamento;
        }
        public void setListaLancamento(List<Lancamento> listaLancamento) {
                this.listaLancamento = listaLancamento;
        }
       
        @Transient
        public List<VendaFormaPagamento> getListaFormaPagamento() {
                return listaFormaPagamento;
        }
        public void setListaFormaPagamento(List<VendaFormaPagamento> listaFormaPagamento) {
                this.listaFormaPagamento = listaFormaPagamento;
        }
       
        @Transient
        public Boolean getNotaFiscalPendente() {
                return notaFiscalPendente;
        }
        public void setNotaFiscalPendente(Boolean notaFiscalPendente) {
                this.notaFiscalPendente = notaFiscalPendente;
        }
       
        @Override
        public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + ((chave == null) ? 0 : chave.hashCode());
                return result;
        }
       
        @Override
        public boolean equals(Object obj) {
                if (this == obj)
                        return true;
                if (obj == null)
                        return false;
                if (getClass() != obj.getClass())
                        return false;
                NotaFiscal other = (NotaFiscal) obj;
                if (chave == null) {
                        if (other.chave != null)
                                return false;
                } else if (!chave.equals(other.chave))
                        return false;
                return true;
        }
       
        @Transient
        public Double getTotalLancamentos() {
                Double total = 0.0;
                if (!VerificadorUtil.isListaNulaOuVazia(getListaLancamento())) {
                        for (Lancamento lancamento : getListaLancamento()) {
                                total = total + lancamento.getValorVenda();
                        }
                }
                return total;  
        }
       
        @Transient
        public Double getTotalPago() {
                Double total = 0.0;
                if (!VerificadorUtil.isListaNulaOuVazia(getListaFormaPagamento())) {
                        for (VendaFormaPagamento vendaFormaPagamento : getListaFormaPagamento()) {
                                total = total + vendaFormaPagamento.getValorPagamento();
                        }
                }
                return total;  
        }
       
        @Transient
        public Double getValorNotaFiscal() {
                if (VerificadorUtil.naoEstaNuloOuVazio(getTextoXml())) {
                        if (getTextoXml().indexOf("<vNF>") > 0) {
                                String valorLocalizado = getTextoXml().substring(getTextoXml().indexOf("<vNF>"), getTextoXml().indexOf("</vNF>"))
                                                                                        .replace("<vNF>", "").replace("</vNF>", "");
                                return new Double(valorLocalizado);
                        }
                }
                return 0.0;
        }
       
        /*
        @Transient
        public Double getTotalValorProdutosRemessa() {
                Double total = new Double(0.0);
                if (VerificadorUtil.naoEstaNuloOuVazio(getListaNFRemessaProdutos())) {
                        for (NotaFiscalProduto notaFiscalProduto : getListaNFRemessaProdutos()) {
                                total = total + notaFiscalProduto.getProduto().getValorCompra() * notaFiscalProduto.getQuantidade();
                        }
                }
                return total;
        }
        */

       
        @Transient
        public Boolean ehNotaFiscalDeRemessa() {
                return VerificadorUtil.naoEstaNulo(getTipoNotaFiscal()) ? getTipoNotaFiscal().equals(TipoNotaFiscal.NFE_REMESSA.getValor()) : false;
        }
       
        @Transient
        public byte[] criarArquivoXml() {
                ByteArrayInputStream in = null;
                ByteArrayOutputStream bos = null;
                try {
                        in = new ByteArrayInputStream(getTextoXml().getBytes());
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                        DocumentBuilder builder = dbf.newDocumentBuilder();
                        Document xml = builder.parse(in);
                       
                        bos = new ByteArrayOutputStream();
                        TransformerFactory transformerFactory = TransformerFactory.newInstance();
                        Transformer transformer = transformerFactory.newTransformer();
                        DOMSource source = new DOMSource(xml);
                        StreamResult result = new StreamResult(bos);
                        transformer.transform(source, result);
                       
                        DefaultStreamedContent arquivo = (DefaultStreamedContent) RelatorioUtils.gerarArquivo(bos.toByteArray(), "ArquivoXML", "xml");
                        return IOUtils.toByteArray(arquivo.getStream());
                } catch (Exception e) {
                        e.printStackTrace();
                } finally {
                        try {
                                in.close();
                                bos.close();
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                }
                return null;
        }
       
        @Transient
        public byte[] getRetornarArquivoXml() {
                setArquivoXml(criarArquivoXml());
                return getArquivoXml();
        }
       
        @Transient
        public void gerarChaveAcessoNfe(String codigoUFEmitente, String dataAAMM, String cnpjCpfEmitente, String modeloNf,
                        String serieNF, String tpEmissao, String numeroNF) {
                try {
            StringBuilder chave = new StringBuilder();
            chave.append(StringUtil.lpadTo(codigoUFEmitente, 2, '0'));
            chave.append(StringUtil.lpadTo(dataAAMM, 4, '0'));
            chave.append(StringUtil.lpadTo(cnpjCpfEmitente.replaceAll("\\D",""), 14, '0'));
            chave.append(StringUtil.lpadTo(modeloNf, 2, '0'));
            chave.append(StringUtil.lpadTo(serieNF, 3, '0'));
            chave.append(StringUtil.lpadTo(String.valueOf(numeroNF), 9, '0'));
            chave.append(StringUtil.lpadTo(tpEmissao, 1, '0'));
            chave.append(StringUtil.lpadTo(numeroNF, 8, '0'));
            chave.append(StringUtil.modulo11(chave.toString()));
            chave.insert(0, "NFe");
            setChave(chave.toString());
        } catch (Exception e) {
                System.out.println(e.toString());
                throw new NegocioException(e.getMessage());
        }
        }
       
        @Transient
        public Long getSequencialDaVenda() {
                return VerificadorUtil.naoEstaNulo(getVenda())? getVenda().getSequencial() : null;
        }
       
        @Transient
        public void preencherNumeroPelaChave() {
                if (VerificadorUtil.naoEstaNuloOuVazio(getChave())) {
                        setNumeroNotaFiscal(new Long(getChave().substring(25, 34)));
                }
        }
       
        @Transient
        public void preencherMotivoPadrao() {
                setMotivoRetorno("Autorizado o uso da NF-e");
        }
       
        @Transient
        public void preencherSeriePadrao() {
                setSerie("1");
        }
       
        @Transient
        public void preencherStatusPadrao() {
                setStatusRetorno("100");
        }
       
        @Transient
        public void preencherQRCodePadrao() {
                setCaminhoQrcode("http://nfce.sefaz.al.gov.br/QRCode/consultarNFCe.jsp?p=" + getChave() + "|2|1|1|437A52AD9DE9BDD04D6BFF55ED997C5199ECC64D");
        }
       
        @Transient
        public String retornarCodigoNumerico() {
                if (VerificadorUtil.naoEstaNuloOuVazio(getChave())) {
                        if (getChave().length() > 42) {
                                return getChave().substring(35, 43);
                        }
                }
                return "";
        }
       
        @Transient
        public void preencherComXML() {
                if (VerificadorUtil.naoEstaNuloOuVazio(this.getTextoXml())) {
                        TNfeProc tNfeProc = unmarshal(this.getTextoXml());
                        preencher(tNfeProc);
                }
               
        }
       
        @Transient
        public void preencher(TNfeProc nfeProc) {
                if (VerificadorUtil.naoEstaNulo(nfeProc)) {
                        if (VerificadorUtil.naoEstaNulo(nfeProc.getNFe())) {
                                if (VerificadorUtil.naoEstaNulo(nfeProc.getNFe().getInfNFe())) {
                                        if (VerificadorUtil.naoEstaNulo(nfeProc.getNFe().getInfNFe().getIde())) {
                                                //this.setCodigoNotaFiscal(new Long(nfeProc.getNFe().getInfNFe().getIde().getCNF()));
                                                this.setNumeroNotaFiscal(new Long(nfeProc.getNFe().getInfNFe().getIde().getNNF()));
                                                this.setSerie(nfeProc.getNFe().getInfNFe().getIde().getSerie());
                                                this.setDataHoraEmissao(DataUtil.retornarDataApartirString("yyyy-MM-dd'T'HH:mm:ss", nfeProc.getNFe().getInfNFe().getIde().getDhEmi()));
                                        }
                                        if (VerificadorUtil.naoEstaNulo(nfeProc.getNFe().getInfNFe().getInfAdic())) {
                                                this.setDescricaoComplementares(nfeProc.getNFe().getInfNFe().getInfAdic().getInfCpl());
                                        }
                                }
                                if (VerificadorUtil.naoEstaNulo(nfeProc.getNFe().getInfNFeSupl())) {}
                                if (VerificadorUtil.naoEstaNulo(nfeProc.getNFe().getSignature())) {}
                        }
                        if (VerificadorUtil.naoEstaNulo(nfeProc.getProtNFe())) {
                                if (VerificadorUtil.naoEstaNulo(nfeProc.getProtNFe().getInfProt())) {
                                        this.setChave(nfeProc.getProtNFe().getInfProt().getChNFe());
                                        this.setDataHoraEvento(DataUtil.retornarDataApartirString("yyyy-MM-dd'T'HH:mm:ss", nfeProc.getProtNFe().getInfProt().getDhRecbto()));
                                        this.setProtocoloAutorizacao(nfeProc.getProtNFe().getInfProt().getNProt());
                                        this.setStatusRetorno(nfeProc.getProtNFe().getInfProt().getCStat());
                                        this.setMotivoRetorno(nfeProc.getProtNFe().getInfProt().getXMotivo());
                                }
                        }
                }
        }
       
        @Transient
        public TNfeProc unmarshal(String stringXml) {
        JAXBContext context = null;
        try {
            context = JAXBContext.newInstance(nfce.TNfeProc.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            return (TNfeProc) unmarshaller.unmarshal(new StreamSource(new StringReader(stringXml)));
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return null;
    }
       
}