diff --git a/l10n_br_account/__manifest__.py b/l10n_br_account/__manifest__.py index f3a57170a6b9..c926d5268bad 100644 --- a/l10n_br_account/__manifest__.py +++ b/l10n_br_account/__manifest__.py @@ -24,9 +24,17 @@ 'views/fiscal_operation_line_view.xml', 'views/account_invoice_view.xml', 'views/account_invoice_line_view.xml', + 'views/fiscal_invoice_view.xml', + 'views/fiscal_invoice_line_view.xml', # Wizards 'wizards/account_invoice_refund_view.xml', + + # Actions + "views/l10n_br_account_action.xml", + + # Menus + "views/l10n_br_account_menu.xml", ], "demo": [ "demo/res_users_demo.xml", diff --git a/l10n_br_account/models/__init__.py b/l10n_br_account/models/__init__.py index 30970651bc03..1027d0157c5a 100644 --- a/l10n_br_account/models/__init__.py +++ b/l10n_br_account/models/__init__.py @@ -11,4 +11,5 @@ from . import account_invoice from . import account_invoice_line from . import fiscal_document +from . import account_move from . import account_move_line diff --git a/l10n_br_account/models/account_invoice.py b/l10n_br_account/models/account_invoice.py index 6cd15182ef43..b33edba5a529 100644 --- a/l10n_br_account/models/account_invoice.py +++ b/l10n_br_account/models/account_invoice.py @@ -2,7 +2,19 @@ # Copyright (C) 2019 - TODAY Raphaël Valyi - Akretion # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -from odoo import api, fields, models +from lxml import etree + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + +from odoo.addons.l10n_br_fiscal.constants.fiscal import ( + FISCAL_OUT, + DOCUMENT_ISSUER_COMPANY, + DOCUMENT_ISSUER_PARTNER, + SITUACAO_EDOC_AUTORIZADA, + SITUACAO_EDOC_CANCELADA, + SITUACAO_EDOC_EM_DIGITACAO, +) INVOICE_TO_OPERATION = { 'out_invoice': 'out', @@ -23,12 +35,21 @@ 'in': ['sale_return', 'out_return'], } -SHADOWED_FIELDS = ['partner_id', 'company_id', 'date', 'currency_id'] +SHADOWED_FIELDS = [ + 'partner_id', + 'company_id', + 'date', + 'currency_id', + 'partner_shipping_id', +] class AccountInvoice(models.Model): _name = 'account.invoice' - _inherit = 'account.invoice' + _inherit = [ + _name, + 'l10n_br_fiscal.document.mixin.methods', + 'l10n_br_fiscal.document.invoice.mixin'] _inherits = {'l10n_br_fiscal.document': 'fiscal_document_id'} _order = 'date_invoice DESC, number DESC' @@ -63,6 +84,16 @@ class AccountInvoice(models.Model): compute='_compute_financial', ) + document_electronic = fields.Boolean( + related='document_type_id.electronic', + 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 @@ -71,9 +102,8 @@ class AccountInvoice(models.Model): comodel_name='l10n_br_fiscal.document', string='Fiscal Document', required=True, + copy=False, ondelete='cascade', - default=lambda self: self.env.ref( - 'l10n_br_fiscal.fiscal_document_dummy'), ) @api.multi @@ -99,9 +129,60 @@ def _prepare_shadowed_fields_dict(self, default=False): return {'default_%s' % (k,): vals[k] for k in vals.keys()} return vals + @api.model + def fields_view_get(self, view_id=None, view_type="form", + toolbar=False, submenu=False): + + order_view = super().fields_view_get( + view_id, view_type, toolbar, submenu + ) + + if view_type == 'form': + view = self.env['ir.ui.view'] + + if (view_id == self.env.ref( + 'l10n_br_account.fiscal_invoice_form').id): + invoice_line_form_id = self.env.ref( + 'l10n_br_account.fiscal_invoice_line_form').id + else: + invoice_line_form_id = self.env.ref( + 'l10n_br_account.invoice_line_form').id + + sub_form_view = self.env['account.invoice.line'].fields_view_get( + view_id=invoice_line_form_id, view_type='form')['arch'] + + sub_form_node = etree.fromstring( + self.env['account.invoice.line'].fiscal_form_view( + sub_form_view)) + + sub_arch, sub_fields = view.postprocess_and_fields( + 'account.invoice.line', sub_form_node, None) + + order_view['fields']['invoice_line_ids']['views']['form'] = {} + + order_view['fields']['invoice_line_ids']['views']['form'][ + 'fields'] = sub_fields + order_view['fields']['invoice_line_ids']['views']['form'][ + 'arch'] = sub_arch + + return order_view + + @api.model + def default_get(self, fields_list): + defaults = super().default_get(fields_list) + invoice_type = self.env.context.get('type', 'out_invoice') + defaults['fiscal_operation_type'] = INVOICE_TO_OPERATION[invoice_type] + if defaults['fiscal_operation_type'] == FISCAL_OUT: + defaults['issuer'] = DOCUMENT_ISSUER_COMPANY + else: + defaults['issuer'] = DOCUMENT_ISSUER_PARTNER + return defaults + @api.model def create(self, values): dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + if not values.get('document_type_id'): + values.update({'fiscal_document_id': dummy_doc.id}) invoice = super().create(values) if invoice.fiscal_document_id != dummy_doc: shadowed_fiscal_vals = invoice._prepare_shadowed_fields_dict() @@ -118,6 +199,14 @@ def write(self, values): invoice.fiscal_document_id.write(shadowed_fiscal_vals) return result + @api.multi + def unlink(self): + """Allows delete a draft or cancelled invoices""" + self.filtered(lambda i: i.state in ('draft', 'cancel')).write( + {'move_name': False} + ) + return super().unlink() + @api.one @api.depends( 'invoice_line_ids.price_total', @@ -128,6 +217,7 @@ def write(self, values): 'date_invoice', 'type') def _compute_amount(self): + self.fiscal_document_id._compute_amount() for inv_line in self.invoice_line_ids: if inv_line.cfop_id: if inv_line.cfop_id.finance_move: @@ -137,7 +227,10 @@ def _compute_amount(self): self.amount_untaxed += inv_line.price_subtotal self.amount_tax += inv_line.price_tax - self.amount_total = self.amount_untaxed + self.amount_tax + self.amount_total = ( + self.amount_untaxed + self.amount_tax - + self.amount_tax_withholding) + amount_total_company_signed = self.amount_total amount_untaxed_signed = self.amount_untaxed if (self.currency_id and self.company_id and @@ -182,6 +275,26 @@ def tax_line_move_line_get(self): # new_tax_lines_dict.append(new_tax) return tax_lines_dict + @api.multi + def finalize_invoice_move_lines(self, move_lines): + lines = super().finalize_invoice_move_lines(move_lines) + dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + financial_lines = [ + l for l in lines if l[2]['account_id'] == self.account_id.id] + + count = 1 + + for l in financial_lines: + if l[2]['debit'] or l[2]['credit']: + if self.fiscal_document_id != dummy_doc: + l[2]['name'] = '{}/{}-{}'.format( + self.fiscal_number, + count, + len(financial_lines) + ) + count += 1 + return lines + @api.multi def get_taxes_values(self): # uncomment these lines @@ -229,3 +342,115 @@ def get_taxes_values(self): tax_grouped[key]['amount'] += val['amount'] tax_grouped[key]['base'] += round_curr(val['base']) return tax_grouped + + @api.onchange('fiscal_operation_id') + def _onchange_fiscal_operation_id(self): + super()._onchange_fiscal_operation_id() + if self.fiscal_operation_id and self.fiscal_operation_id.journal_id: + self.journal_id = self.fiscal_operation_id.journal_id + + @api.multi + def open_fiscal_document(self): + if self.env.context.get('type', '') == 'out_invoice': + action = self.env.ref( + 'l10n_br_account.fiscal_invoice_out_action').read()[0] + elif self.env.context.get('type', '') == 'in_invoice': + action = self.env.ref( + 'l10n_br_account.fiscal_invoice_in_action').read()[0] + else: + action = self.env.ref( + 'l10n_br_account.fiscal_invoice_all_action').read()[0] + form_view = [ + (self.env.ref('l10n_br_account.fiscal_invoice_form').id, 'form')] + if 'views' in action: + action['views'] = form_view + [ + (state, view) for state, view in action['views'] + if view != 'form'] + else: + action['views'] = form_view + action['res_id'] = self.id + return action + + @api.multi + def action_date_assign(self): + """Usamos esse método para definir a data de emissão do documento + fiscal e numeração do documento fiscal para ser usado nas linhas + dos lançamentos contábeis.""" + super().action_date_assign() + dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + 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 + + @api.multi + def action_move_create(self): + result = super().action_move_create() + dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + self.mapped('fiscal_document_id').filtered( + lambda d: d != dummy_doc).action_document_confirm() + return result + + @api.multi + def action_invoice_draft(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_CANCELADA: + if i.issuer == DOCUMENT_ISSUER_COMPANY: + raise UserError(_( + "You can't set this document number: {} to draft " + "because this document is cancelled in SEFAZ".format( + i.fiscal_number))) + if i.state_edoc != SITUACAO_EDOC_EM_DIGITACAO: + i.fiscal_document_id.action_document_back2draft() + return super().action_invoice_draft() + + @api.multi + def action_document_send(self): + dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + invoices = self.filtered(lambda d: d.fiscal_document_id != dummy_doc) + if invoices: + invoices.mapped('fiscal_document_id').action_document_send() + for invoice in invoices: + invoice.move_id.post(invoice=invoice) + + @api.multi + 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() + + @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" + )) + + @api.multi + def action_document_back2draft(self): + """Sets fiscal document to draft state and cancel and set to draft + the related invoice for both documents remain equivalent state.""" + dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + for i in self.filtered(lambda d: d.fiscal_document_id != dummy_doc): + i.action_cancel() + i.action_invoice_draft() + + def view_xml(self): + self.ensure_one() + return self.fiscal_document_id.view_xml() + + def view_pdf(self): + self.ensure_one() + return self.fiscal_document_id.view_pdf() diff --git a/l10n_br_account/models/account_invoice_line.py b/l10n_br_account/models/account_invoice_line.py index 777705bf79e3..66421623b85a 100644 --- a/l10n_br_account/models/account_invoice_line.py +++ b/l10n_br_account/models/account_invoice_line.py @@ -4,6 +4,13 @@ from odoo import api, fields, models +from odoo.addons.l10n_br_fiscal.constants.fiscal import ( + TAX_FRAMEWORK, + # FISCAL_IN_OUT, +) + +from .account_invoice import INVOICE_TO_OPERATION + # These fields that have the same name in account.invoice.line # and l10n_br_fiscal.document.line.mixin. So they won't be updated # by the _inherits system. An alternative would be changing their name @@ -17,9 +24,7 @@ class AccountInvoiceLine(models.Model): _name = 'account.invoice.line' - _inherit = ['account.invoice.line', - 'l10n_br_fiscal.document.line.mixin.methods', - 'l10n_br_account.document.line.mixin'] + _inherit = [_name, 'l10n_br_fiscal.document.line.mixin.methods'] _inherits = {'l10n_br_fiscal.document.line': 'fiscal_document_line_id'} # initial account.invoice.line inherits on fiscal.document.line that are @@ -39,9 +44,69 @@ class AccountInvoiceLine(models.Model): comodel_name='l10n_br_fiscal.document.line', string='Fiscal Document Line', required=True, + copy=False, ondelete='cascade', - default=lambda self: self.env.ref( - 'l10n_br_fiscal.fiscal_document_line_dummy'), + ) + + document_type_id = fields.Many2one( + comodel_name='l10n_br_fiscal.document.type', + related='invoice_id.document_type_id', + ) + + tax_framework = fields.Selection( + selection=TAX_FRAMEWORK, + related='invoice_id.company_id.tax_framework', + string='Tax Framework', + ) + + cfop_destination = fields.Selection( + related="cfop_id.destination", + string="CFOP Destination" + ) + + partner_id = fields.Many2one( + comodel_name='res.partner', + related='invoice_id.partner_id', + string='Partner', + ) + + partner_company_type = fields.Selection( + related="partner_id.company_type" + ) + + fiscal_genre_code = fields.Char( + related="fiscal_genre_id.code", + string="Fiscal Product Genre Code", + ) + + icms_cst_code = fields.Char( + related="icms_cst_id.code", + string="ICMS CST Code", + ) + + ipi_cst_code = fields.Char( + related="ipi_cst_id.code", + string="IPI CST Code", + ) + + cofins_cst_code = fields.Char( + related="cofins_cst_id.code", + string="COFINS CST Code", + ) + + cofinsst_cst_code = fields.Char( + related="cofinsst_cst_id.code", + string="COFINS ST CST Code", + ) + + pis_cst_code = fields.Char( + related="pis_cst_id.code", + string="PIS CST Code", + ) + + pisst_cst_code = fields.Char( + related="pisst_cst_id.code", + string="PIS ST CST Code", ) @api.one @@ -60,6 +125,7 @@ class AccountInvoiceLine(models.Model): def _compute_price(self): currency = self.invoice_id and self.invoice_id.currency_id or None taxes = {} + self._update_taxes() if self.invoice_line_tax_ids: taxes = self.invoice_line_tax_ids.compute_all( price_unit=self.price_unit, @@ -126,14 +192,24 @@ def _prepare_shadowed_fields_dict(self, default=False): return {"default_%s" % (k,): vals[k] for k in vals.keys()} return vals + @api.model + def default_get(self, fields_list): + defaults = super().default_get(fields_list) + inv_type = self.env.context.get('type', 'out_invoice') + defaults['fiscal_operation_type'] = INVOICE_TO_OPERATION[inv_type] + return defaults + @api.model def create(self, values): - dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') - if self.env['account.invoice'].browse( - values['invoice_id']).fiscal_document_id != dummy_doc: - values['fiscal_document_line_id'] = False + dummy_doc_line_id = self.env.ref( + 'l10n_br_fiscal.fiscal_document_line_dummy').id + dummy_doc_id = self.env.ref('l10n_br_fiscal.fiscal_document_dummy').id + fiscal_doc_id = self.env['account.invoice'].browse( + values['invoice_id']).fiscal_document_id.id + if dummy_doc_id == fiscal_doc_id: + values['fiscal_document_line_id'] = dummy_doc_line_id line = super().create(values) - if line.invoice_id.fiscal_document_id != dummy_doc: + if dummy_doc_id != fiscal_doc_id: shadowed_fiscal_vals = line._prepare_shadowed_fields_dict() doc_id = line.invoice_id.fiscal_document_id.id shadowed_fiscal_vals['document_id'] = doc_id @@ -146,10 +222,35 @@ def write(self, values): 'l10n_br_fiscal.fiscal_document_line_dummy') if values.get('invoice_id'): values['document_id'] = self.env[ - "account.invoice"].browse(values['invoice_id']).fiscal_document_id.id + "account.invoice"].browse( + values['invoice_id']).fiscal_document_id.id result = super().write(values) for line in self: if line.fiscal_document_line_id != dummy_doc_line: shadowed_fiscal_vals = line._prepare_shadowed_fields_dict() line.fiscal_document_line_id.write(shadowed_fiscal_vals) return result + + @api.multi + def unlink(self): + dummy_doc_line_id = self.env.ref( + 'l10n_br_fiscal.fiscal_document_line_dummy').id + unlink_fiscal_lines = self.env['l10n_br_fiscal.document.line'] + for inv_line in self: + if not inv_line.exists(): + continue + if inv_line.fiscal_document_line_id.id != dummy_doc_line_id: + unlink_fiscal_lines |= inv_line.fiscal_document_line_id + result = super().unlink() + unlink_fiscal_lines.unlink() + self.clear_caches() + return result + + @api.onchange('fiscal_tax_ids') + def _onchange_fiscal_tax_ids(self): + super()._onchange_fiscal_tax_ids() + user_type = 'sale' + if self.invoice_id.type in ('in_invoice', 'in_refund'): + user_type = 'purchase' + self.invoice_line_tax_ids |= self.fiscal_tax_ids.account_taxes( + user_type=user_type) diff --git a/l10n_br_account/models/account_move.py b/l10n_br_account/models/account_move.py new file mode 100644 index 000000000000..55dcde553985 --- /dev/null +++ b/l10n_br_account/models/account_move.py @@ -0,0 +1,25 @@ +# Copyright (C) 2021 - TODAY Renato Lima - Akretion +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from odoo import api, models + +from odoo.addons.l10n_br_fiscal.constants.fiscal import ( + SITUACAO_EDOC_AUTORIZADA, + DOCUMENT_ISSUER_COMPANY, +) + + +class AccountMove(models.Model): + _inherit = 'account.move' + + @api.multi + def post(self, invoice=False): + dummy_doc = self.env.ref('l10n_br_fiscal.fiscal_document_dummy') + result = super().post(invoice) + if invoice: + if (invoice.fiscal_document_id != dummy_doc + and invoice.document_electronic + and invoice.issuer == DOCUMENT_ISSUER_COMPANY + and invoice.state_edoc != SITUACAO_EDOC_AUTORIZADA): + self.button_cancel() + return result diff --git a/l10n_br_account/models/fiscal_document.py b/l10n_br_account/models/fiscal_document.py index a34f649a5b3e..ee0e20ecc976 100644 --- a/l10n_br_account/models/fiscal_document.py +++ b/l10n_br_account/models/fiscal_document.py @@ -14,14 +14,10 @@ class FiscalDocument(models.Model): @api.multi def unlink(self): - draft_documents = self.filtered( - lambda d: d.state == SITUACAO_EDOC_EM_DIGITACAO) + non_draft_documents = self.filtered( + lambda d: d.state != SITUACAO_EDOC_EM_DIGITACAO) - if draft_documents: + if non_draft_documents: UserError(_("You cannot delete a fiscal document " "which is not draft state.")) - - invoices = self.env['account.invoice'].search( - [('fiscal_document_id', 'in', self.ids)]) - invoices.unlink() return super().unlink() diff --git a/l10n_br_account/models/fiscal_operation.py b/l10n_br_account/models/fiscal_operation.py index a989fec4950e..97bd745760b5 100644 --- a/l10n_br_account/models/fiscal_operation.py +++ b/l10n_br_account/models/fiscal_operation.py @@ -2,7 +2,18 @@ # Copyright (C) 2019 - TODAY Raphaël Valyi - Akretion # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -from odoo import fields, models +from odoo import api, fields, models +from odoo.addons.account.models.account_invoice import TYPE2JOURNAL + +FISCAL_TYPE_INVOICE = { + 'purchase': 'in_invoice', + 'purchase_refund': 'in_refund', + 'return_in': 'in_refund', + 'sale': 'out_invoice', + 'sale_refund': 'out_refund', + 'return_out': 'out_refund', + 'other': 'out_invoice', +} class Operation(models.Model): @@ -22,3 +33,40 @@ class Operation(models.Model): string='Fiscal Position', company_dependent=True, ) + + @api.multi + def _change_action_view(self, action): + fiscal_op_type = action.get('context') + if fiscal_op_type == 'out': + new_action = self.env.ref( + 'l10n_br_account.fiscal_invoice_out_action') + elif fiscal_op_type == 'in': + new_action = self.env.ref( + 'l10n_br_account.fiscal_invoice_out_action') + else: + new_action = self.env.ref( + 'l10n_br_account.fiscal_invoice_all_action') + invoice_type = FISCAL_TYPE_INVOICE[self.fiscal_type] + journal_type = TYPE2JOURNAL[invoice_type] + new_action['context'] = ({ + 'type': invoice_type, + 'default_fiscal_operation_type': self.fiscal_type, + 'default_fiscal_operation_id': self.id, + 'journal_type': journal_type, + }) + new_action['domain'] = action.get('domain', {}) + return new_action.read()[0] + + @api.multi + def action_create_new(self): + action = super().action_create_new() + action['res_model'] = 'account.invoice' + action['view_id'] = self.env.ref( + 'l10n_br_account.fiscal_invoice_form').id + action['context'] = self._change_action_view(action)['context'] + return action + + @api.multi + def open_action(self): + action = super().open_action() + return self._change_action_view(action) diff --git a/l10n_br_account/views/account_invoice_line_view.xml b/l10n_br_account/views/account_invoice_line_view.xml index ce84c049d1dd..5264f7bbe3bb 100644 --- a/l10n_br_account/views/account_invoice_line_view.xml +++ b/l10n_br_account/views/account_invoice_line_view.xml @@ -1,74 +1,54 @@ - - diff --git a/l10n_br_account/views/account_invoice_view.xml b/l10n_br_account/views/account_invoice_view.xml index 300c49a25e81..086a27a5562b 100644 --- a/l10n_br_account/views/account_invoice_view.xml +++ b/l10n_br_account/views/account_invoice_view.xml @@ -11,6 +11,23 @@ + + ['|','|','|', '|', ('fiscal_number','ilike',self), ('number','ilike',self), ('origin','ilike',self), ('reference', 'ilike', self), ('partner_id', 'child_of', self)] + Account Number + + + + + + l10n_br_account.invoice.tree + account.invoice + + + + + + + + + {'invisible': [('document_type_id', '!=', False)]} + + +

+
+ + : + + +
+

+
@@ -27,45 +62,61 @@ - - - - - - + + + + + + + + + + + + + + + {'default_company_id': company_id, 'default_partner_id': partner_id, 'default_fiscal_operation_id': fiscal_operation_id, 'default_document_type_id': document_type_id} + + + + + + + 1 + + + + + + +
- - + l10n_br_account.invoice.supplier.form account.invoice + +
+ +
+
@@ -73,54 +124,46 @@ - - - - - - + + + + + + + + + + + + + + + {'default_company_id': company_id, 'default_partner_id': partner_id, 'default_fiscal_operation_type': fiscal_operation_type, 'default_fiscal_operation_id': fiscal_operation_id, 'default_document_type_id': document_type_id} + + + + + + + 1 + + + + + + +
- - l10n_br_account.invoice.line.form - account.invoice.line - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/l10n_br_account/views/fiscal_invoice_line_view.xml b/l10n_br_account/views/fiscal_invoice_line_view.xml new file mode 100644 index 000000000000..ce053614a7b6 --- /dev/null +++ b/l10n_br_account/views/fiscal_invoice_line_view.xml @@ -0,0 +1,28 @@ + + + + + l10n_br_account.invoice.line.form + account.invoice.line + + primary + + + + + + + + + + + + + + + + + + + + diff --git a/l10n_br_account/views/fiscal_invoice_view.xml b/l10n_br_account/views/fiscal_invoice_view.xml new file mode 100644 index 000000000000..c4973e7c36af --- /dev/null +++ b/l10n_br_account/views/fiscal_invoice_view.xml @@ -0,0 +1,114 @@ + + + + + l10n_br_account.fiscal.invoice.search + account.invoice + + primary + + + + + + + + + + + + + l10n_br_account.fiscal.invoice.tree + account.invoice + + primary + + + + + + + + + + + + + + + + + l10n_br_account.fiscal.invoice.form + account.invoice + + primary + + + + + + + + + {'invisible': [('state_edoc', 'not in', ('a_enviar', 'rejeitada'))]} + + + + {'invisible': [('state_edoc', '!=', 'autorizada')]} + + + + {'invisible': ['|', ('state_edoc', 'in', ('autorizada', 'cancelada', 'denegada')), ('fiscal_number', '=', False)]} + + + + {'invisible': ['|', ('state_edoc', '=', 'em_digitacao'), ('document_electronic', '=', False)]} + + + + {'invisible': ['|', ('state_edoc', '=', 'em_digitacao'), ('document_electronic', '=', False)]} + + + + - diff --git a/l10n_br_repair/models/repair_order.py b/l10n_br_repair/models/repair_order.py index 2e2f7b37e008..a9850cd680c0 100644 --- a/l10n_br_repair/models/repair_order.py +++ b/l10n_br_repair/models/repair_order.py @@ -515,7 +515,7 @@ def action_invoice_create(self, group=False): # Check if there more than one Document Type if ((fiscal_document_type != - invoice_created_by_super.document_type_id.id) or + invoice_created_by_super.document_type_id) or (len(document_type_list) > 1)): # Remove the First Document Type, # already has Invoice created diff --git a/l10n_br_sale/models/sale_order.py b/l10n_br_sale/models/sale_order.py index 6d8851fea94d..2e8bdb9f3e27 100644 --- a/l10n_br_sale/models/sale_order.py +++ b/l10n_br_sale/models/sale_order.py @@ -108,12 +108,6 @@ def _fiscal_operation_domain(self): digits=dp.get_precision('Account'), ) - fiscal_document_count = fields.Integer( - string='Fiscal Document Count', - related='invoice_count', - readonly=True, - ) - comment_ids = fields.Many2many( comodel_name='l10n_br_fiscal.comment', relation='sale_order_comment_rel', @@ -191,29 +185,6 @@ def _onchange_fiscal_operation_id(self): super()._onchange_fiscal_operation_id() self.fiscal_position_id = self.fiscal_operation_id.fiscal_position_id - @api.multi - def action_view_document(self): - invoices = self.mapped('invoice_ids') - action = self.env.ref('l10n_br_fiscal.document_out_action').read()[0] - if len(invoices) > 1: - action['domain'] = [ - ('id', 'in', invoices.mapped('fiscal_document_id').ids), - ] - elif len(invoices) == 1: - form_view = [ - (self.env.ref('l10n_br_fiscal.document_form').id, 'form'), - ] - if 'views' in action: - action['views'] = form_view + [(state, view) for state, view - in action['views'] if - view != 'form'] - else: - action['views'] = form_view - action['res_id'] = invoices.fiscal_document_id.id - else: - action = {'type': 'ir.actions.act_window_close'} - return action - @api.multi def _prepare_invoice(self): self.ensure_one() @@ -259,6 +230,9 @@ def action_invoice_create(self, grouped=False, final=False): # Identify how many Document Types exist for inv_line in invoice_created_by_super.invoice_line_ids: + if inv_line.display_type: + continue + fiscal_document_type = \ inv_line.fiscal_operation_line_id.get_document_type( inv_line.invoice_id.company_id) @@ -318,3 +292,31 @@ def action_invoice_create(self, grouped=False, final=False): inv_line.invoice_id = invoice.id return inv_ids + + # TODO open by default Invoice view with Fiscal Details Button + # You can add a group to select default view Fiscal Invoice or + # Account invoice. + # @api.multi + # def action_view_invoice(self): + # action = super().action_view_invoice() + # invoices = self.mapped('invoice_ids') + # if any(invoices.filtered(lambda i: i.document_type_id)): + # action = self.env.ref( + # 'l10n_br_account.fiscal_invoice_out_action').read()[0] + # if len(invoices) > 1: + # action['domain'] = [('id', 'in', invoices.ids)] + # elif len(invoices) == 1: + # form_view = [ + # (self.env.ref( + # 'l10n_br_account.fiscal_invoice_form').id, 'form') + # ] + # if 'views' in action: + # action['views'] = form_view + [ + # (state, view) for state, view in action['views'] + # if view != 'form'] + # else: + # action['views'] = form_view + # action['res_id'] = invoices.ids[0] + # else: + # action = {'type': 'ir.actions.act_window_close'} + # return action diff --git a/l10n_br_sale/views/sale_view.xml b/l10n_br_sale/views/sale_view.xml index 08ceabbfd1c1..a695a82f30fb 100644 --- a/l10n_br_sale/views/sale_view.xml +++ b/l10n_br_sale/views/sale_view.xml @@ -21,11 +21,6 @@ 99 - - diff --git a/l10n_br_sale_stock/models/stock_move.py b/l10n_br_sale_stock/models/stock_move.py index b933b1768e0a..7e2c9196f72d 100644 --- a/l10n_br_sale_stock/models/stock_move.py +++ b/l10n_br_sale_stock/models/stock_move.py @@ -31,9 +31,4 @@ def _get_new_picking_values(self): self.sale_line_id.order_id._prepare_br_fiscal_dict() values.update(super()._get_new_picking_values()) - # TODO - remover o pop abaixo depois do merge - # https://github.com/OCA/l10n-brazil/pull/1099 - # , não é necessário - # Remover o dummy - values.pop('fiscal_document_id') return values diff --git a/l10n_br_stock_account/models/stock_picking.py b/l10n_br_stock_account/models/stock_picking.py index 81d73cc8ba13..647c70edb3fb 100644 --- a/l10n_br_stock_account/models/stock_picking.py +++ b/l10n_br_stock_account/models/stock_picking.py @@ -49,26 +49,3 @@ def _fiscal_operation_domain(self): invoice_state = fields.Selection( copy=True, ) - - @api.multi - def action_view_document(self): - invoices = self.mapped('invoice_ids') - action = self.env.ref('l10n_br_fiscal.document_out_action').read()[0] - if len(invoices) > 1: - action['domain'] = [ - ('id', 'in', invoices.mapped('fiscal_document_id').ids), - ] - elif len(invoices) == 1: - form_view = [ - (self.env.ref('l10n_br_fiscal.document_form').id, 'form'), - ] - if 'views' in action: - action['views'] = form_view + [(state, view) for state, view - in action['views'] if - view != 'form'] - else: - action['views'] = form_view - action['res_id'] = invoices.fiscal_document_id.id - else: - action = {'type': 'ir.actions.act_window_close'} - return action diff --git a/l10n_br_stock_account/views/stock_picking.xml b/l10n_br_stock_account/views/stock_picking.xml index 33bdcb57d1fe..4fc67a6ecdd0 100644 --- a/l10n_br_stock_account/views/stock_picking.xml +++ b/l10n_br_stock_account/views/stock_picking.xml @@ -35,17 +35,6 @@ -
- -