Trust-Code/odoo-brasil

View on GitHub
br_nfe/models/account_invoice.py

Summary

Maintainability
A
3 hrs
Test Coverage
# -*- coding: utf-8 -*-
# © 2016 Danimar Ribeiro, Trustcode
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import api, fields, models
from odoo.exceptions import UserError


class AccountInvoice(models.Model):
    _inherit = 'account.invoice'

    @api.multi
    def _compute_nfe_number(self):
        for item in self:
            docs = self.env['invoice.eletronic'].search(
                [('invoice_id', '=', item.id)])
            if docs:
                item.nfe_number = docs[0].numero
                item.nfe_exception_number = docs[0].numero
                item.nfe_exception = (docs[0].state in ('error', 'denied'))
                item.sending_nfe = docs[0].state == 'draft'
                item.nfe_status = '%s - %s' % (
                    docs[0].codigo_retorno, docs[0].mensagem_retorno)

    @api.multi
    @api.depends("document_serie_id")
    def _compute_nfe_next_number(self):
        for item in self:
            if item.state == 'draft':
                seq_id = item.sudo().document_serie_id.internal_sequence_id
                self.nfe_next_number = seq_id.number_next_actual

    ambiente_nfe = fields.Selection(
        string="Ambiente NFe", related="company_id.tipo_ambiente",
        readonly=True)
    sending_nfe = fields.Boolean(
        string="Enviando NFe?", compute="_compute_nfe_number")
    nfe_exception = fields.Boolean(
        string="Problemas na NFe?", compute="_compute_nfe_number")
    nfe_status = fields.Char(
        string="Mensagem NFe", compute="_compute_nfe_number")
    nfe_number = fields.Integer(
        string=u"Número NFe", compute="_compute_nfe_number")
    nfe_exception_number = fields.Integer(
        string=u"Número NFe", compute="_compute_nfe_number")
    nfe_next_number = fields.Integer(
        string=u"* Número NF-e", readonly=True,
        compute="_compute_nfe_next_number",
        help="Númeração da NF-e a ser gerada, " +
        "caso outra fatura não seja validada.")

    @api.multi
    def action_invoice_draft(self):
        for item in self:
            docs = self.env['invoice.eletronic'].search(
                [('invoice_id', '=', item.id)])
            for doc in docs:
                if doc.state in ('done', 'denied', 'cancel'):
                    raise UserError('Nota fiscal já emitida para esta fatura - \
                                    Duplique a fatura para continuar')
        return super(AccountInvoice, self).action_invoice_draft()

    @api.multi
    def action_number(self):
        super(AccountInvoice, self).action_number()
        if self.fiscal_document_id.code == '55':
            if not self.document_serie_id:
                return
            serie_id = self.document_serie_id
            seq_id = serie_id.sudo().internal_sequence_id
            number_next_actual = seq_id.number_next_actual
            inv_inutilized = self.env['invoice.eletronic.inutilized'].search([
                ('serie', '=', serie_id.id),
                ('numeration_start', '<', number_next_actual),
                ('numeration_end', '>', number_next_actual)])

            if len(inv_inutilized) > 0:
                raise UserError(u"Número gerado para NF-e inutilizado.")

        return True

    def invoice_print(self):
        if self.fiscal_document_id.code == '55':
            docs = self.env['invoice.eletronic'].search(
                [('invoice_id', '=', self.id)])
            return self.env['report'].get_action(
                docs.ids, 'nfe.custom_report_danfe')
        else:
            return super(AccountInvoice, self).invoice_print()

    def _return_pdf_invoice(self, doc):
        if self.fiscal_document_id.code == '55':
            return 'nfe.custom_report_danfe'
        return super(AccountInvoice, self)._return_pdf_invoice(doc)

    def _prepare_edoc_vals(self, inv):
        res = super(AccountInvoice, self)._prepare_edoc_vals(inv)

        res['payment_mode_id'] = inv.payment_mode_id.id
        res['ind_pres'] = inv.fiscal_position_id.ind_pres
        res['finalidade_emissao'] = inv.fiscal_position_id.finalidade_emissao
        res['informacoes_legais'] = inv.fiscal_comment
        res['informacoes_complementares'] = inv.comment
        res['numero_fatura'] = inv.number
        res['fatura_bruto'] = inv.total_bruto
        res['fatura_desconto'] = inv.total_desconto
        res['fatura_liquido'] = inv.amount_total
        res['pedido_compra'] = inv.name
        res['valor_icms_uf_remet'] = inv.valor_icms_uf_remet
        res['valor_icms_uf_dest'] = inv.valor_icms_uf_dest
        res['valor_icms_fcp_uf_dest'] = inv.valor_icms_fcp_uf_dest

        res['ambiente'] = 'homologacao' \
            if inv.company_id.tipo_ambiente == '2' else 'producao'

        # Indicador Consumidor Final
        if inv.commercial_partner_id.is_company:
            res['ind_final'] = '0'
        else:
            res['ind_final'] = '1'
        res['ind_dest'] = '1'
        if inv.company_id.state_id != inv.commercial_partner_id.state_id:
            res['ind_dest'] = '2'
        if inv.company_id.country_id != inv.commercial_partner_id.country_id:
            res['ind_dest'] = '3'
        if inv.fiscal_position_id.ind_final:
            res['ind_final'] = inv.fiscal_position_id.ind_final

        # Indicador IE Destinatário
        ind_ie_dest = False
        if inv.commercial_partner_id.is_company:
            if inv.commercial_partner_id.inscr_est:
                ind_ie_dest = '1'
            elif inv.commercial_partner_id.state_id.code in ('AM', 'BA', 'CE',
                                                             'GO', 'MG', 'MS',
                                                             'MT', 'PE', 'RN',
                                                             'SP'):
                ind_ie_dest = '9'
            else:
                ind_ie_dest = '2'
        else:
            ind_ie_dest = '9'
        if inv.commercial_partner_id.indicador_ie_dest:
            ind_ie_dest = inv.commercial_partner_id.indicador_ie_dest
        res['ind_ie_dest'] = ind_ie_dest

        # Duplicatas
        duplicatas = []
        count = 1
        for parcela in inv.receivable_move_line_ids.sorted(lambda x: x.date_maturity):
            duplicatas.append((0, None, {
                'numero_duplicata': "%03d" % count,
                'data_vencimento': parcela.date_maturity,
                'valor': parcela.credit or parcela.debit,
            }))
            count += 1
        res['duplicata_ids'] = duplicatas

        # Documentos Relacionados
        documentos = []
        for doc in inv.fiscal_document_related_ids:
            documentos.append((0, None, {
                'invoice_related_id': doc.invoice_related_id.id,
                'document_type': doc.document_type,
                'access_key': doc.access_key,
                'serie': doc.serie,
                'internal_number': doc.internal_number,
                'state_id': doc.state_id.id,
                'cnpj_cpf': doc.cnpj_cpf,
                'cpfcnpj_type': doc.cpfcnpj_type,
                'inscr_est': doc.inscr_est,
                'date': doc.date,
                'fiscal_document_id': doc.fiscal_document_id.id,
            }))

        res['fiscal_document_related_ids'] = documentos
        return res

    def _prepare_edoc_item_vals(self, invoice_line):
        vals = super(AccountInvoice, self).\
            _prepare_edoc_item_vals(invoice_line)
        vals['cest'] = invoice_line.product_id.cest or \
            invoice_line.fiscal_classification_id.cest or ''
        vals['classe_enquadramento_ipi'] = \
            invoice_line.fiscal_classification_id.classe_enquadramento or ''
        vals['codigo_enquadramento_ipi'] = \
            invoice_line.fiscal_classification_id.codigo_enquadramento or '999'
        vals['tem_difal'] = invoice_line.tem_difal
        vals['icms_bc_uf_dest'] = invoice_line.icms_bc_uf_dest
        vals['icms_aliquota_interestadual'] = \
            invoice_line.tax_icms_inter_id.amount or 0.0
        vals['icms_aliquota_inter_part'] = \
            invoice_line.icms_aliquota_inter_part or 0.0
        vals['icms_aliquota_uf_dest'] = \
            invoice_line.tax_icms_intra_id.amount or 0.0
        vals['icms_aliquota_fcp_uf_dest'] = \
            invoice_line.tax_icms_fcp_id.amount or 0.0
        vals['icms_uf_remet'] = invoice_line.icms_uf_remet or 0.0
        vals['icms_uf_dest'] = invoice_line.icms_uf_dest or 0.0
        vals['icms_fcp_uf_dest'] = invoice_line.icms_fcp_uf_dest or 0.0
        vals['icms_aliquota_inter_part'] = \
            invoice_line.icms_aliquota_inter_part or 0.0

        di_importacao = []
        for di in invoice_line.import_declaration_ids:
            adicoes = []
            for di_line in di.line_ids:
                adicoes.append((0, None, {
                    'sequence': di_line.sequence,
                    'name': di_line.name,
                    'manufacturer_code': di_line.manufacturer_code,
                    'amount_discount': di_line.amount_discount,
                    'drawback_number': di_line.drawback_number,
                }))
            di_importacao.append((0, None, {
                'name': di.name,
                'date_registration': di.date_registration,
                'state_id': di.state_id.id,
                'location': di.location,
                'date_release': di.date_release,
                'type_transportation': di.type_transportation,
                'afrmm_value': di.afrmm_value,
                'type_import': di.type_import,
                'thirdparty_cnpj': di.thirdparty_cnpj,
                'thirdparty_state_id': di.thirdparty_state_id.id,
                'exporting_code': di.exporting_code,
                'line_ids': adicoes,
            }))
        vals['import_declaration_ids'] = di_importacao
        vals['informacao_adicional'] = invoice_line.informacao_adicional
        return vals