From 224d1212c46e9d74bf365dc2989e806b10fba09e Mon Sep 17 00:00:00 2001 From: Danimar Ribeiro Date: Thu, 19 Nov 2020 05:08:29 -0300 Subject: [PATCH] =?UTF-8?q?Novo=20m=C3=B3dulo=20para=20emiss=C3=A3o=20de?= =?UTF-8?q?=20nfse=20para=20duque=20de=20caxias?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- br_nfse_issnet/__init__.py | 4 + br_nfse_issnet/__manifest__.py | 26 ++ br_nfse_issnet/models/__init__.py | 6 + br_nfse_issnet/models/account_invoice.py | 19 + br_nfse_issnet/models/br_account_service.py | 12 + br_nfse_issnet/models/invoice_eletronic.py | 388 +++++++++++++++ br_nfse_issnet/reports/danfse_issnet.xml | 492 ++++++++++++++++++++ br_nfse_issnet/static/description/icon.png | Bin 0 -> 4388 bytes br_nfse_issnet/views/br_account_service.xml | 14 + 9 files changed, 961 insertions(+) create mode 100644 br_nfse_issnet/__init__.py create mode 100644 br_nfse_issnet/__manifest__.py create mode 100644 br_nfse_issnet/models/__init__.py create mode 100644 br_nfse_issnet/models/account_invoice.py create mode 100644 br_nfse_issnet/models/br_account_service.py create mode 100644 br_nfse_issnet/models/invoice_eletronic.py create mode 100644 br_nfse_issnet/reports/danfse_issnet.xml create mode 100644 br_nfse_issnet/static/description/icon.png create mode 100644 br_nfse_issnet/views/br_account_service.xml diff --git a/br_nfse_issnet/__init__.py b/br_nfse_issnet/__init__.py new file mode 100644 index 000000000..f6140bb38 --- /dev/null +++ b/br_nfse_issnet/__init__.py @@ -0,0 +1,4 @@ +# © 2016 Danimar Ribeiro , Trustcode +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models diff --git a/br_nfse_issnet/__manifest__.py b/br_nfse_issnet/__manifest__.py new file mode 100644 index 000000000..f26daa0e8 --- /dev/null +++ b/br_nfse_issnet/__manifest__.py @@ -0,0 +1,26 @@ +# © 2020 Danimar Ribeiro , Trustcode +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ # pylint: disable=C8101,C8103 + 'name': 'Envio de NFS-e ISSNet', + 'summary': """Permite o envio de NFS-e ISSNet através das faturas do Odoo + Mantido por Trustcode""", + 'description': 'Envio de NFS-e - ISSNet', + 'version': '12.0.1.0.0', + 'category': 'account', + 'author': 'Trustcode', + 'license': 'AGPL-3', + 'website': 'http://www.trustcode.com.br', + 'contributors': [ + 'Danimar Ribeiro ', + ], + 'depends': [ + 'br_nfse', + ], + 'data': [ + 'views/br_account_service.xml', + 'reports/danfse_issnet.xml', + ], + 'installable': True, + 'application': True, +} diff --git a/br_nfse_issnet/models/__init__.py b/br_nfse_issnet/models/__init__.py new file mode 100644 index 000000000..27f46d810 --- /dev/null +++ b/br_nfse_issnet/models/__init__.py @@ -0,0 +1,6 @@ +# © 2020 Danimar Ribeiro , Trustcode +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import br_account_service +from . import account_invoice +from . import invoice_eletronic diff --git a/br_nfse_issnet/models/account_invoice.py b/br_nfse_issnet/models/account_invoice.py new file mode 100644 index 000000000..946a97dca --- /dev/null +++ b/br_nfse_issnet/models/account_invoice.py @@ -0,0 +1,19 @@ +# © 2020 Danimar Ribeiro, Trustcode +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class AccountInvoice(models.Model): + _inherit = 'account.invoice' + + def _return_pdf_invoice(self, doc): + if doc.model == '006': # ISS.Net + return 'br_nfse_issnet.report_br_nfse_danfe_issnet' + return super(AccountInvoice, self)._return_pdf_invoice(doc) + + def _prepare_edoc_item_vals(self, line): + res = super(AccountInvoice, self)._prepare_edoc_item_vals(line) + res['codigo_tributacao_municipio'] = \ + line.service_type_id.codigo_tributacao_municipio + return res diff --git a/br_nfse_issnet/models/br_account_service.py b/br_nfse_issnet/models/br_account_service.py new file mode 100644 index 000000000..81028e362 --- /dev/null +++ b/br_nfse_issnet/models/br_account_service.py @@ -0,0 +1,12 @@ +# © 2020 Danimar Ribeiro , Trustcode +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class BrAccountServiceType(models.Model): + _inherit = 'br_account.service.type' + + codigo_tributacao_municipio = fields.Char( + string=u"Cód. Tribut. Munic.", size=20, + help="Código de Tributação no Munípio") diff --git a/br_nfse_issnet/models/invoice_eletronic.py b/br_nfse_issnet/models/invoice_eletronic.py new file mode 100644 index 000000000..cf5312951 --- /dev/null +++ b/br_nfse_issnet/models/invoice_eletronic.py @@ -0,0 +1,388 @@ +# © 2020 Danimar Ribeiro , Trustcode +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import re +import pytz +import time +import base64 +import logging +from odoo import api, fields, models +from odoo.exceptions import UserError +from odoo.tools.safe_eval import safe_eval + +_logger = logging.getLogger(__name__) + +try: + from pytrustnfe.nfse.issnet import xml_recepcionar_lote_rps + from pytrustnfe.nfse.issnet import recepcionar_lote_rps + from pytrustnfe.nfse.issnet import consultar_lote_rps + from pytrustnfe.nfse.issnet import cancelar_nfse + from pytrustnfe.certificado import Certificado +except ImportError: + _logger.error('Cannot import pytrustnfe', exc_info=True) + + +STATE = {'edit': [('readonly', False)]} + + +class InvoiceEletronicItem(models.Model): + _inherit = 'invoice.eletronic.item' + + codigo_tributacao_municipio = fields.Char( + string=u"Cód. Tribut. Munic.", size=20, readonly=True, + help="Código de Tributação no Munípio", states=STATE) + + +class InvoiceEletronic(models.Model): + _inherit = 'invoice.eletronic' + + state = fields.Selection( + selection_add=[('waiting', 'Esperando processamento')]) + + def _get_state_to_send(self): + res = super(InvoiceEletronic, self)._get_state_to_send() + return res + ('waiting',) + + @api.depends('valor_retencao_pis', 'valor_retencao_cofins', + 'valor_retencao_irrf', 'valor_retencao_inss', + 'valor_retencao_csll') + def _compute_total_retencoes(self): + for item in self: + total = item.valor_retencao_pis + item.valor_retencao_cofins + \ + item.valor_retencao_irrf + item.valor_retencao_inss + \ + item.valor_retencao_csll + item.retencoes_federais = total + + retencoes_federais = fields.Monetary( + string="Retenções Federais", compute=_compute_total_retencoes) + + @api.multi + def _hook_validation(self): + errors = super(InvoiceEletronic, self)._hook_validation() + if self.model == '006': + issqn_codigo = '' + if not self.company_id.inscr_mun: + errors.append(u'Inscrição municipal obrigatória') + if not self.company_id.cnae_main_id.code: + errors.append(u'CNAE Principal da empresa obrigatório') + for eletr in self.eletronic_item_ids: + prod = u"Produto: %s - %s" % (eletr.product_id.default_code, + eletr.product_id.name) + if eletr.tipo_produto == 'product': + errors.append( + u'Esse documento permite apenas serviços - %s' % prod) + if eletr.tipo_produto == 'service': + if not eletr.issqn_codigo: + errors.append(u'%s - Código de Serviço' % prod) + if not issqn_codigo: + issqn_codigo = eletr.issqn_codigo + if issqn_codigo != eletr.issqn_codigo: + errors.append(u'%s - Apenas itens com o mesmo código \ + de serviço podem ser enviados' % prod) + if not eletr.codigo_tributacao_municipio: + errors.append(u'%s - %s - Código de tributação do município \ + obrigatório' % ( + eletr.product_id.name, + eletr.product_id.service_type_id.name)) + + return errors + + @api.multi + def _prepare_eletronic_invoice_values(self): + res = super(InvoiceEletronic, self)._prepare_eletronic_invoice_values() + if self.model != '006': + return res + + tz = pytz.timezone(self.env.user.partner_id.tz) or pytz.utc + dt_emissao = pytz.utc.localize(self.data_emissao).astimezone(tz) + dt_emissao = dt_emissao.strftime('%Y-%m-%dT%H:%M:%S') + + partner = self.commercial_partner_id + city_tomador = partner.city_id + tomador = { + 'tipo_cpfcnpj': 2 if partner.is_company else 1, + 'cnpj_cpf': re.sub('[^0-9]', '', + partner.cnpj_cpf or ''), + 'razao_social': partner.legal_name or partner.name, + 'logradouro': partner.street or '', + 'numero': partner.number or '', + 'complemento': partner.street2 or '', + 'bairro': partner.district or 'Sem Bairro', + 'cidade': '%s%s' % (city_tomador.state_id.ibge_code, + city_tomador.ibge_code), + 'uf': partner.state_id.code, + 'cep': re.sub('[^0-9]', '', partner.zip), + 'telefone': re.sub('[^0-9]', '', partner.phone or ''), + 'inscricao_municipal': re.sub( + '[^0-9]', '', partner.inscr_mun or ''), + 'email': self.partner_id.email or partner.email or '', + } + city_prestador = self.company_id.partner_id.city_id + prestador = { + 'cnpj': re.sub( + '[^0-9]', '', self.company_id.partner_id.cnpj_cpf or ''), + 'inscricao_municipal': re.sub( + '[^0-9]', '', self.company_id.partner_id.inscr_mun or ''), + 'cidade': '%s%s' % (city_prestador.state_id.ibge_code, + city_prestador.ibge_code), + 'cnae': re.sub('[^0-9]', '', self.company_id.cnae_main_id.code) + } + + itens_servico = [] + descricao = '' + codigo_servico = '' + for item in self.eletronic_item_ids: + descricao += item.name + '\n' + itens_servico.append({ + 'descricao': item.name, + 'quantidade': str("%.2f" % item.quantidade), + 'valor_unitario': str("%.2f" % item.preco_unitario) + }) + codigo_servico = re.sub('[^0-9]', '', item.issqn_codigo) + + rps = { + 'numero': self.numero, + 'serie': self.serie.code or '', + 'tipo_rps': '1', + 'data_emissao': dt_emissao, + 'natureza_operacao': '1', # Tributada no municipio + 'regime_tributacao': '2', # Estimativa + 'optante_simples': # 1 - Sim, 2 - Não + '2' if self.company_id.fiscal_type == '3' else '1', + 'incentivador_cultural': '2', # 2 - Não + 'status': '1', # 1 - Normal + 'valor_servico': str("%.2f" % self.valor_servicos), + 'valor_deducao': '0', + 'valor_pis': str("%.2f" % self.valor_retencao_pis), + 'valor_cofins': str("%.2f" % self.valor_retencao_cofins), + 'valor_inss': str("%.2f" % self.valor_retencao_inss), + 'valor_ir': str("%.2f" % self.valor_retencao_irrf), + 'valor_csll': str("%.2f" % self.valor_retencao_csll), + 'iss_retido': '1' if self.valor_retencao_issqn > 0 else '2', + 'valor_iss': str("%.2f" % self.valor_issqn), + 'valor_iss_retido': str("%.2f" % self.valor_retencao_issqn), + 'base_calculo': str("%.2f" % self.valor_bc_issqn), + 'aliquota_issqn': str("%.4f" % ( + self.eletronic_item_ids[0].issqn_aliquota / 100)), + 'valor_liquido_nfse': str("%.2f" % self.valor_final), + 'codigo_servico': int(codigo_servico), + 'codigo_tributacao_municipio': + self.eletronic_item_ids[0].codigo_tributacao_municipio, + # '01.07.00 / 00010700', + 'descricao': descricao, + 'codigo_municipio': prestador['cidade'], + 'itens_servico': itens_servico, + 'tomador': tomador, + 'prestador': prestador, + } + + nfse_vals = { + 'numero_lote': self.id, + 'inscricao_municipal': prestador['inscricao_municipal'], + 'cnpj_prestador': prestador['cnpj'], + 'lista_rps': [rps], + } + + res.update(nfse_vals) + return res + + @api.multi + def action_post_validate(self): + super(InvoiceEletronic, self).action_post_validate() + if self.model not in ('006'): + return + + cert = self.company_id.with_context( + {'bin_size': False}).nfe_a1_file + cert_pfx = base64.decodestring(cert) + + certificado = Certificado( + cert_pfx, self.company_id.nfe_a1_password) + + nfse_values = self._prepare_eletronic_invoice_values() + xml_enviar = xml_recepcionar_lote_rps(certificado, nfse=nfse_values) + + self.xml_to_send = base64.encodestring(xml_enviar.encode('utf-8')) + self.xml_to_send_name = 'nfse-enviar-%s.xml' % self.numero + + def _find_attachment_ids_email(self): + atts = super(InvoiceEletronic, self)._find_attachment_ids_email() + if self.model not in ('006'): + return atts + + attachment_obj = self.env['ir.attachment'] + danfe_report = self.env['ir.actions.report'].search( + [('report_name', '=', + 'br_nfse_issnet.main_template_br_nfse_danfe_issnet')]) + report_service = danfe_report.xml_id + report_name = safe_eval(danfe_report.print_report_name, + {'object': self, 'time': time}) + danfse, dummy = self.env.ref(report_service).render_qweb_pdf([self.id]) + filename = "%s.%s" % (report_name, "pdf") + if danfse: + danfe_id = attachment_obj.create(dict( + name=filename, + datas_fname=filename, + datas=base64.b64encode(danfse), + mimetype='application/pdf', + res_model='account.invoice', + res_id=self.invoice_id.id, + )) + atts.append(danfe_id.id) + return atts + + @api.multi + def action_send_eletronic_invoice(self): + super(InvoiceEletronic, self).action_send_eletronic_invoice() + if self.model != '006' or self.state in ('done', 'cancel'): + return + self.state = 'error' + + cert = self.company_id.with_context( + {'bin_size': False}).nfe_a1_file + cert_pfx = base64.decodestring(cert) + + certificado = Certificado( + cert_pfx, self.company_id.nfe_a1_password) + + consulta_lote = None + recebe_lote = None + + # Envia o lote apenas se não existir protocolo + if not self.recibo_nfe: + xml_to_send = base64.decodestring(self.xml_to_send) + recebe_lote = recepcionar_lote_rps( + certificado, xml=xml_to_send, ambiente=self.ambiente) + + retorno = recebe_lote['object'] + if "NumeroLote" in dir(retorno): + self.recibo_nfe = retorno.Protocolo + # Espera alguns segundos antes de consultar + time.sleep(5) + else: + mensagem_retorno = retorno.ListaMensagemRetorno\ + .MensagemRetorno + self.codigo_retorno = mensagem_retorno.Codigo + self.mensagem_retorno = mensagem_retorno.Mensagem + self._create_attachment( + 'nfse-ret', self, + recebe_lote['received_xml']) + return + # Monta a consulta de situação do lote + # 1 - Não Recebido + # 2 - Não processado + # 3 - Processado com erro + # 4 - Processado com sucesso + obj = { + 'cnpj_prestador': re.sub( + '[^0-9]', '', self.company_id.cnpj_cpf), + 'inscricao_municipal': re.sub( + '[^0-9]', '', self.company_id.inscr_mun), + 'protocolo': self.recibo_nfe, + } + consulta_situacao = consultar_situacao_lote( + certificado, consulta=obj, ambiente=self.ambiente) + ret_rec = consulta_situacao['object'] + + if "Situacao" in dir(ret_rec): + if ret_rec.Situacao in (3, 4): + + consulta_lote = consultar_lote_rps( + certificado, consulta=obj, ambiente=self.ambiente) + retLote = consulta_lote['object'] + + if "ListaNfse" in dir(retLote): + self.state = 'done' + self.codigo_retorno = '100' + self.mensagem_retorno = 'NFSe emitida com sucesso' + self.verify_code = retLote.ListaNfse.CompNfse \ + .Nfse.InfNfse.CodigoVerificacao + self.numero_nfse = \ + retLote.ListaNfse.CompNfse.Nfse.InfNfse.Numero + else: + mensagem_retorno = retLote.ListaMensagemRetorno \ + .MensagemRetorno + self.codigo_retorno = mensagem_retorno.Codigo + self.mensagem_retorno = mensagem_retorno.Mensagem + + elif ret_rec.Situacao == 1: # Reenviar caso não recebido + self.codigo_retorno = '' + self.mensagem_retorno = 'Aguardando envio' + self.state = 'draft' + else: + self.state = 'waiting' + self.codigo_retorno = '2' + self.mensagem_retorno = 'Lote aguardando processamento' + else: + self.codigo_retorno = \ + ret_rec.ListaMensagemRetorno.MensagemRetorno.Codigo + self.mensagem_retorno = \ + ret_rec.ListaMensagemRetorno.MensagemRetorno.Mensagem + + self.env['invoice.eletronic.event'].create({ + 'code': self.codigo_retorno, + 'name': self.mensagem_retorno, + 'invoice_eletronic_id': self.id, + }) + if recebe_lote: + self._create_attachment( + 'nfse-ret', self, + recebe_lote['received_xml']) + if consulta_lote: + self._create_attachment( + 'rec', self, consulta_lote['sent_xml']) + self._create_attachment( + 'rec-ret', self, + consulta_lote['received_xml']) + + @api.multi + def action_cancel_document(self, context=None, justificativa=None): + if self.model not in ('006'): + return super(InvoiceEletronic, self).action_cancel_document( + justificativa=justificativa) + + cert = self.company_id.with_context( + {'bin_size': False}).nfe_a1_file + cert_pfx = base64.decodestring(cert) + + certificado = Certificado( + cert_pfx, self.company_id.nfe_a1_password) + + company = self.company_id + city_prestador = self.company_id.partner_id.city_id + canc = { + 'cnpj_prestador': re.sub('[^0-9]', '', company.cnpj_cpf), + 'inscricao_municipal': re.sub('[^0-9]', '', company.inscr_mun), + 'cidade': '%s%s' % (city_prestador.state_id.ibge_code, + city_prestador.ibge_code), + 'numero_nfse': self.numero_nfse, + 'codigo_cancelamento': '1', + 'senha': self.company_id.senha_ambiente_nfse + } + cancel = cancelar_nfse( + certificado, cancelamento=canc, ambiente=self.ambiente) + retorno = cancel['object'].Body.CancelarNfseResponse.CancelarNfseResult + if "Cancelamento" in dir(retorno): + self.state = 'cancel' + self.codigo_retorno = '100' + self.mensagem_retorno = u'Nota Fiscal de Serviço Cancelada' + else: + # E79 - Nota já está cancelada + if retorno.ListaMensagemRetorno.MensagemRetorno.Codigo != 'E79': + mensagem = "%s - %s" % ( + retorno.ListaMensagemRetorno.MensagemRetorno.Codigo, + retorno.ListaMensagemRetorno.MensagemRetorno.Mensagem + ) + raise UserError(mensagem) + + self.state = 'cancel' + self.codigo_retorno = '100' + self.mensagem_retorno = u'Nota Fiscal de Serviço Cancelada' + + self.env['invoice.eletronic.event'].create({ + 'code': self.codigo_retorno, + 'name': self.mensagem_retorno, + 'invoice_eletronic_id': self.id, + }) + self._create_attachment('canc', self, cancel['sent_xml']) + self._create_attachment('canc-ret', self, cancel['received_xml']) diff --git a/br_nfse_issnet/reports/danfse_issnet.xml b/br_nfse_issnet/reports/danfse_issnet.xml new file mode 100644 index 000000000..5c720aec7 --- /dev/null +++ b/br_nfse_issnet/reports/danfse_issnet.xml @@ -0,0 +1,492 @@ + + + + + + + Danfe ISS.Net + + Portrait + 3 + 3 + 3 + 3 + + 3 + + + + + Nota de Serviço - ISS.Net + '%s - NF - %s' % (object.numero, object.partner_id.name) + + + + + + + + diff --git a/br_nfse_issnet/static/description/icon.png b/br_nfse_issnet/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ba1ff5653cffbea53c4f24cc361299b149cf9bd0 GIT binary patch literal 4388 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 + + + + view.br_nfse_issnet.account.service.type.form + br_account.service.type + + + + + + + +