diff --git a/l10n_br_account/__manifest__.py b/l10n_br_account/__manifest__.py index ca1b44ad85cc..8940a90963fe 100644 --- a/l10n_br_account/__manifest__.py +++ b/l10n_br_account/__manifest__.py @@ -29,6 +29,7 @@ # Wizards 'wizards/account_invoice_refund_view.xml', + 'wizards/wizard_document_status.xml', # Actions "views/l10n_br_account_action.xml", diff --git a/l10n_br_account/models/account_invoice.py b/l10n_br_account/models/account_invoice.py index cc7060720fd4..8bc626c5ccde 100644 --- a/l10n_br_account/models/account_invoice.py +++ b/l10n_br_account/models/account_invoice.py @@ -12,7 +12,6 @@ FISCAL_OUT, DOCUMENT_ISSUER_COMPANY, DOCUMENT_ISSUER_PARTNER, - SITUACAO_EDOC_AUTORIZADA, SITUACAO_EDOC_CANCELADA, SITUACAO_EDOC_EM_DIGITACAO, ) @@ -90,11 +89,6 @@ class AccountInvoice(models.Model): string='Electronic?', ) - fiscal_number = fields.Char( - string='Fiscal Number', - copy=False, - ) - # this default should be overwritten to False in a module pretending to # create fiscal documents from the invoices. But this default here # allows to install the l10n_br_account module without creating issues @@ -107,6 +101,16 @@ class AccountInvoice(models.Model): ondelete='cascade', ) + document_type = fields.Char( + related='document_type_id.code', + stored=True, + ) + + @api.multi + def _get_amount_lines(self): + """Get object lines instaces used to compute fields""" + return self.mapped('invoice_line_ids') + @api.multi def _get_amount_lines(self): """Get object lines instaces used to compute fields""" @@ -309,7 +313,9 @@ def finalize_invoice_move_lines(self, move_lines): if l[2]['debit'] or l[2]['credit']: if self.fiscal_document_id != dummy_doc: l[2]['name'] = '{}/{}-{}'.format( - self.fiscal_number, + self.fiscal_document_id.with_context( + fiscal_document_no_company=True + )._compute_document_name(), count, len(financial_lines) ) @@ -404,11 +410,8 @@ def action_date_assign(self): for invoice in self: if invoice.fiscal_document_id != dummy_doc: if invoice.issuer == DOCUMENT_ISSUER_COMPANY: - invoice.fiscal_document_id.document_date() - invoice.fiscal_document_id.document_number() - invoice.fiscal_number = invoice.fiscal_document_id.number - else: - invoice.fiscal_document_id.number = invoice.fiscal_number + invoice.fiscal_document_id._document_date() + invoice.fiscal_document_id._document_number() @api.multi def action_move_create(self): @@ -427,7 +430,7 @@ def action_invoice_draft(self): raise UserError(_( "You can't set this document number: {} to draft " "because this document is cancelled in SEFAZ".format( - i.fiscal_number))) + i.document_number))) if i.state_edoc != SITUACAO_EDOC_EM_DIGITACAO: i.fiscal_document_id.action_document_back2draft() return super().action_invoice_draft() @@ -445,21 +448,19 @@ def action_document_send(self): def action_document_cancel(self): dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): - if i.state_edoc == SITUACAO_EDOC_AUTORIZADA: - return i.fiscal_document_id.action_document_cancel() + return i.fiscal_document_id.action_document_cancel() @api.multi def action_document_correction(self): dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): - if i.state_edoc in SITUACAO_EDOC_AUTORIZADA: - if i.issuer == DOCUMENT_ISSUER_COMPANY: - return i.fiscal_document_id.action_document_correction() - else: - raise UserError(_( - "You cannot create a fiscal correction document if " - "this fical document you are not the document issuer" - )) + return i.fiscal_document_id.action_document_correction() + + @api.multi + def action_document_invalidate(self): + dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): + return i.fiscal_document_id.action_document_invalidate() @api.multi def action_document_back2draft(self): @@ -470,6 +471,13 @@ def action_document_back2draft(self): i.action_cancel() i.action_invoice_draft() + @api.multi + def action_invoice_cancel(self): + dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): + return i.fiscal_document_id.action_document_cancel() + return super().action_invoice_cancel() + def view_xml(self): self.ensure_one() return self.fiscal_document_id.view_xml() diff --git a/l10n_br_account/views/account_invoice_view.xml b/l10n_br_account/views/account_invoice_view.xml index ffd95b4305f2..9bca68b17499 100644 --- a/l10n_br_account/views/account_invoice_view.xml +++ b/l10n_br_account/views/account_invoice_view.xml @@ -12,7 +12,7 @@ - ['|','|','|', '|', ('fiscal_number','ilike',self), ('number','ilike',self), ('origin','ilike',self), ('reference', 'ilike', self), ('partner_id', 'child_of', self)] + ['|','|','|', '|', ('document_number','ilike',self), ('number','ilike',self), ('origin','ilike',self), ('reference', 'ilike', self), ('partner_id', 'child_of', self)] Account Number @@ -25,7 +25,7 @@ - + - + - + - + - - + + @@ -72,19 +39,6 @@ - - nfe.40.detpag.form - nfe.40.detpag - -
- - - - -
-
-
- nfe.40.vol.form nfe.40.vol @@ -99,133 +53,4 @@
- - nfe.40.transporta.form - nfe.40.transporta - -
- - - - - - - - -
-
-
- - - l10n_br_nfe.document.form - l10n_br_fiscal.document - -
- - - - -
-
- -
-

- : - -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - -
- -
-
- diff --git a/l10n_br_nfse/__init__.py b/l10n_br_nfse/__init__.py index aee8895e7a31..0650744f6bc6 100644 --- a/l10n_br_nfse/__init__.py +++ b/l10n_br_nfse/__init__.py @@ -1,2 +1 @@ from . import models -from . import wizards diff --git a/l10n_br_nfse/__manifest__.py b/l10n_br_nfse/__manifest__.py index f059aa495288..147a3df97bbd 100644 --- a/l10n_br_nfse/__manifest__.py +++ b/l10n_br_nfse/__manifest__.py @@ -30,8 +30,6 @@ 'views/document_line_view.xml', 'views/res_company_view.xml', - 'wizards/wizard_document_status.xml', - 'report/danfse.xml', ], 'demo': [ diff --git a/l10n_br_nfse/models/document.py b/l10n_br_nfse/models/document.py index 336f62d79de4..2f91031a5e69 100644 --- a/l10n_br_nfse/models/document.py +++ b/l10n_br_nfse/models/document.py @@ -1,6 +1,7 @@ # Copyright 2019 KMEE INFORMATICA LTDA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import base64 from requests import Session import logging @@ -11,10 +12,11 @@ from odoo import api, fields, models from odoo.addons.l10n_br_fiscal.constants.fiscal import ( + EVENT_ENV_HML, + EVENT_ENV_PROD, MODELO_FISCAL_NFSE, - TAX_FRAMEWORK_SIMPLES_ALL, - DOCUMENT_ISSUER_COMPANY, PROCESSADOR_OCA, + TAX_FRAMEWORK_SIMPLES_ALL, ) from ..constants.nfse import ( NFSE_ENVIRONMENTS, @@ -50,11 +52,6 @@ class Document(models.Model): copy=False, ) - rps_number = fields.Char( - string='RPS Number', - copy=False, - index=True, - ) rps_type = fields.Selection( string='RPS Type', selection=RPS_TYPE, @@ -81,17 +78,36 @@ class Document(models.Model): default=lambda self: self.env.user.company_id.nfse_environment, ) - def document_number(self): + @api.multi + def _document_date(self): + super()._document_date() for record in self.filtered(filter_processador_edoc_nfse): - if record.issuer == DOCUMENT_ISSUER_COMPANY: - if record.document_serie_id: - record.document_serie = record.document_serie_id.code - if not record.rps_number and record.date: - record.rps_number = record.document_serie_id.\ - next_seq_number() - record.number = record.rps_number - super(Document, self - self.filtered(filter_processador_edoc_nfse) - ).document_number() + if not record.date_in_out: + record.date_in_out = fields.Datetime.now() + + def make_pdf(self): + if not self.filtered(filter_processador_edoc_nfse): + return super().make_pdf() + pdf = self.env.ref( + 'l10n_br_nfse.report_br_nfse_danfe').render_qweb_pdf(self.ids)[0] + self.file_report_id.unlink() + + if self.document_number: + filename = 'NFS-e-' + self.document_number + '.pdf' + else: + filename = 'RPS-' + self.rps_number + '.pdf' + + self.file_report_id = self.env['ir.attachment'].create( + { + "name": filename, + "datas_fname": filename, + "res_model": self._name, + "res_id": self.id, + "datas": base64.b64encode(pdf), + "mimetype": "application/pdf", + "type": "binary", + } + ) def _processador_erpbrasil_nfse(self): certificado = cert.Certificado( @@ -122,9 +138,16 @@ def _document_export(self, pretty_print=True): processador = record._processador_erpbrasil_nfse() xml_file = processador.\ _generateds_to_string_etree(edoc, pretty_print=pretty_print)[0] - event_id = self._gerar_evento(xml_file, event_type="0") + event_id = self.event_ids.create_event_save_xml( + company_id=self.company_id, + environment=( + EVENT_ENV_PROD if self.nfe_environment == '1' else EVENT_ENV_HML), + event_type="0", + xml_file=xml_file, + document_id=self, + ) _logger.debug(xml_file) - record.autorizacao_event_id = event_id + record.authorization_event_id = event_id def _prepare_dados_servico(self): self.line_ids.ensure_one() @@ -147,10 +170,6 @@ def _prepare_dados_tomador(self): def _prepare_lote_rps(self): num_rps = self.rps_number - - dh_emi = fields.Datetime.context_timestamp( - self, fields.Datetime.from_string(self.date) - ).strftime('%Y-%m-%dT%H:%M:%S') return { 'cnpj': misc.punctuation_rm(self.company_id.partner_id.cnpj_cpf), 'inscricao_municipal': misc.punctuation_rm( @@ -159,7 +178,11 @@ def _prepare_lote_rps(self): 'numero': num_rps, 'serie': self.document_serie_id.code or '', 'tipo': self.rps_type, - 'data_emissao': dh_emi, + 'data_emissao': fields.Datetime.context_timestamp( + self, fields.Datetime.from_string(self.document_date) + ).strftime('%Y-%m-%dT%H:%M:%S'), + 'date_in_out': fields.Datetime.context_timestamp( + self, self.date_in_out).strftime('%Y-%m-%dT%H:%M:%S'), 'natureza_operacao': self.operation_nature, 'regime_especial_tributacao': self.taxation_special_regime, 'optante_simples_nacional': '1' @@ -174,3 +197,23 @@ def _prepare_lote_rps(self): 'carga_tributaria': self.amount_tax, 'total_recebido': self.amount_total, } + + def convert_type_nfselib(self, class_object, object_filed, value): + if value is None: + return value + + value_type = '' + for field in class_object().member_data_items_: + if field.name == object_filed: + value_type = field.child_attrs.get('type', '').\ + replace('xsd:', '') + break + + if value_type in ('int', 'byte', 'nonNegativeInteger'): + return int(value) + elif value_type == 'decimal': + return float(value) + elif value_type == 'string': + return str(value) + else: + return value diff --git a/l10n_br_nfse/report/danfse.xml b/l10n_br_nfse/report/danfse.xml index ca7c1337dae4..e71533e4329f 100644 --- a/l10n_br_nfse/report/danfse.xml +++ b/l10n_br_nfse/report/danfse.xml @@ -24,7 +24,7 @@ Nota de Serviço - '%s - NF - %s' % (object.number, object.partner_id.name) + '%s - NF - %s' % (object.document_number, object.partner_id.name)