Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
# -*- encoding: utf-8 -*-
#################################################################################
# #
# Copyright (C) 2012 Cloves Almeida - Brblue #
# #
#This program is free software: you can redistribute it and/or modify #
#it under the terms of the GNU Affero General Public License as published by #
#the Free Software Foundation, either version 3 of the License, or #
#(at your option) any later version. #
# #
#This program is distributed in the hope that it will be useful, #
#but WITHOUT ANY WARRANTY; without even the implied warranty of #
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
#GNU Affero General Public License for more details. #
# #
#You should have received a copy of the GNU Affero General Public License #
#along with this program. If not, see <http://www.gnu.org/licenses/>. #
#################################################################################
from osv import osv
from rule_core import match
import logging
log = logging.getLogger('rule_faturamento')
def apply_rules(inv_obj, cr, uid, ids, context):
""" Add fiscal parameters to invoice."""
line_obj = inv_obj.pool.get('account.invoice.line')
for inv in inv_obj.browse(cr, uid, ids):
#######
# Section A: Mapping Odoo invoice header data to domain specific data.
#######
# Issuer
emit = inv.company_id
# Receiver
parc = inv.address_invoice_id
# Is it an outgoing invoice]?
nota_saida = inv.type in ('out_invoice', 'in_refund')
# Are issuer and receiver on the same state?
mesma_uf = (emit.state_id.code == parc.state_id.code) \
and (emit.country_id.code == parc.country_id.code)
# Is the partner a corporation?
parc_contribuinte = parc.partner_id.partner_fiscal_type_id.code in ['JUR-C','JUR-SN']
# What form of accounting the issuer uses (Simplified, Regular)
regime_apuracao = inv.company_id.fiscal_type
# What is the fiscal operation (a regular sale, a consigned sale, a demonstration shipment, etc)
natureza_operacao = inv.fiscal_operation_category_id.code
for line in inv.invoice_line:
#######
# Section B: Mapping Odoo invoice line tax rules
#######
# Is it the case for fiscal substition (hard-coded false, we're not subject to such rule)
venda_st = False
#######
# Section C: Expressing Odoo invoice header line tax rules
#######
vals = {}
# Rule CST ICMS
# We're using a Python coded decision-table! How cool is that?!
# The first row is the domain fact we want to match, acting also as table header.
# The other rows are the values to match against facts. "None" means to always match.
# The last column is the value returned on match.
# The imported match function return the matched row or None.
table = [
(regime_apuracao, venda_st, natureza_operacao, {'icms_cst': None}),
("1", False, 'Venda', {'icms_cst': 102}),
("1", False, 'RemessaMostruario', {'icms_cst': 900}),
("1", False, 'DevolucaoMostruario', {'icms_cst': 900}),
("1", False, 'DevolucaoVenda', {'icms_cst': 900}),
]
vals.update(match(table))
if not vals['icms_cst']:
raise osv.except_osv(u'Erro!', u"Não foi possível identificar o CST ICMS para a operação.'")
# Rule CST IPI
table = [
(regime_apuracao, {'ipi_cst': None}),
("1", {'ipi_cst': 99}),
]
vals.update(match(table))
if not vals['ipi_cst']:
raise osv.except_osv(u'Erro!', u"Não foi possível identificar o CST IPI para a operação.'")
# Rule CST PIS
table = [
(regime_apuracao, {'pis_cst': None}),
("1", {'pis_cst': 99}),
]
vals.update(match(table))
if not vals['pis_cst']:
raise osv.except_osv(u'Erro!', u"Não foi possível identificar o CST PIS para a operação.'")
# Rule CST COFINS
table = [
(regime_apuracao, {'cofins_cst': None}),
("1", {'cofins_cst': 99}),
]
vals.update(match(table))
if not vals['cofins_cst']:
raise osv.except_osv(u'Erro!', u"Não foi possível identificar o CST COFINS para a operação.'")
# Rule CFOP
table = [
(mesma_uf, nota_saida, natureza_operacao, parc_contribuinte, {'cfop': None}),
(True, True, 'Venda', None, {'cfop': 5101}),
(False, True, 'Venda', True, {'cfop': 6101}),
(False, True, 'Venda', False, {'cfop': 6107}),
(True, True, 'RemessaMostruario', None, {'cfop': 5949}),
(False, True, 'RemessaMostruario', None, {'cfop': 6949}),
(True, False, 'DevolucaoMostruario', None, {'cfop': 1949}),
(False, False, 'DevolucaoMostruario', None, {'cfop': 2949}),
(True, False, 'DevolucaoVenda', None, {'cfop': 1201}),
(False, False, 'DevolucaoVenda', None, {'cfop': 2201}),
]
cfop = match(table)['cfop']
if not cfop:
raise osv.except_osv(u'Erro!', u"Não foi possível identificar o CFOP para a operação.")
else:
# In CFOP we return the natural key and lookup the object id.
cfop_ids = inv_obj.pool.get('l10n_br_account.cfop').search(cr, uid, [('code', '=', cfop)])
if len(cfop_ids) < 1:
raise osv.except_osv(u'Erro!', u"CFOP %s não cadastrado." % cfop)
vals['cfop_id'] = cfop_ids[0]
# Update line changes
line.write(vals)
#######
# Section C: Expressing Odoo invoice header tax rules
#######
vals = {}
# Rule Obligatory Notes for Simplified Accounting
if regime_apuracao == "1" and natureza_operacao in ['Venda', 'RemessaMostruario']:
vals['comment'] = (inv.comment or '') + 'DOCUMENTO EMITIDO POR ME OU EPP OPTANTE PELO SIMPLES NACIONAL; NAO GERA DIREITO A CREDITO FISCAL DE ICMS, DE ISS E DE IPI. '
# Rule Obligatory Notes for Demonstration Shippment and Returns
# We can use if-else conditions too.
if natureza_operacao == 'RemessaMostruario':
vals['comment'] += 'MERCADORIA ENVIADA PARA COMPOR MOSTRUARIO DE VENDA.'
vals['natureza_operacao'] = 'REMESSA P/ MOSTRUARIO'
elif natureza_operacao == 'DevolucaoMostruario':
vals['natureza_operacao'] = 'RETORNO DE MOSTRUARIO'
elif natureza_operacao == 'DevolucaoVenda':
vals['natureza_operacao'] = 'DEVOLUCAO DE VENDA'
# Rule Freight Code
if not (inv.incoterm and inv.incoterm.freight_responsibility):
cif_id = inv_obj.pool.get('stock.incoterms').search(cr, uid, [('code', '=', 'CIF')])[0]
vals['incoterm'] = cif_id
# Update
inv.write(vals)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.