From bcd2afacb0f7713eab61f1e69378edcbd439713f Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Tue, 14 Feb 2023 13:33:23 -0300 Subject: [PATCH 001/609] [14.0][MIG]-l10n_br_sped_efd_pis_cofins --- l10n_br_sped_efd_contribuicoes/README.rst | 13 + l10n_br_sped_efd_contribuicoes/__init__.py | 4 + .../__manifest__.py | 21 + .../models/__init__.py | 4 + .../models/sped_efd_contribuicoes.py | 1153 +++++++++++++++++ .../security/ir.model.access.csv | 2 + .../views/sped_contribuicoes_view.xml | 64 + 7 files changed, 1261 insertions(+) create mode 100755 l10n_br_sped_efd_contribuicoes/README.rst create mode 100755 l10n_br_sped_efd_contribuicoes/__init__.py create mode 100755 l10n_br_sped_efd_contribuicoes/__manifest__.py create mode 100755 l10n_br_sped_efd_contribuicoes/models/__init__.py create mode 100644 l10n_br_sped_efd_contribuicoes/models/sped_efd_contribuicoes.py create mode 100644 l10n_br_sped_efd_contribuicoes/security/ir.model.access.csv create mode 100644 l10n_br_sped_efd_contribuicoes/views/sped_contribuicoes_view.xml diff --git a/l10n_br_sped_efd_contribuicoes/README.rst b/l10n_br_sped_efd_contribuicoes/README.rst new file mode 100755 index 00000000..723a3d2e --- /dev/null +++ b/l10n_br_sped_efd_contribuicoes/README.rst @@ -0,0 +1,13 @@ +# Copyright (C) 2020 - Carlos R. Silveira - ATSti Soluções +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +SPED EFD Contribuições(Pis/Cofins) +========================= + +* Este modulo gera o arquivo do SPED EFD Contribuições(Pis/Cofins) +* Depende da biblioteca : https://github.com/sped-br/python-sped + +Contributors +------------ + +* Carlos R. Silveira diff --git a/l10n_br_sped_efd_contribuicoes/__init__.py b/l10n_br_sped_efd_contribuicoes/__init__.py new file mode 100755 index 00000000..a65727ec --- /dev/null +++ b/l10n_br_sped_efd_contribuicoes/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2020 - Carlos R. Silveira - ATSti Soluções +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import models \ No newline at end of file diff --git a/l10n_br_sped_efd_contribuicoes/__manifest__.py b/l10n_br_sped_efd_contribuicoes/__manifest__.py new file mode 100755 index 00000000..44305538 --- /dev/null +++ b/l10n_br_sped_efd_contribuicoes/__manifest__.py @@ -0,0 +1,21 @@ +# Copyright (C) 2020 - Carlos R. Silveira - ATSti Soluções +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +{ + 'name': 'Sped EFD Contribuições (PIS/COFINS))', + 'summary': """ Gera arquivo Sped EFD Contribuições PIS/COFINS""", + 'version': '1.0', + 'category': 'Localisation', + 'author': 'ATSti Solucoes', + 'website': 'http://www.atsti.com.br', + 'license': 'AGPL-3', + 'contributors': [ + 'Carlos R. Silveira', + ], + 'data': [ + 'security/ir.model.access.csv', + 'views/sped_contribuicoes_view.xml', + ], + 'demo': [], + 'installable': True, +} diff --git a/l10n_br_sped_efd_contribuicoes/models/__init__.py b/l10n_br_sped_efd_contribuicoes/models/__init__.py new file mode 100755 index 00000000..1d357e84 --- /dev/null +++ b/l10n_br_sped_efd_contribuicoes/models/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2020 - Carlos R. Silveira - ATSti Soluções +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import sped_efd_contribuicoes diff --git a/l10n_br_sped_efd_contribuicoes/models/sped_efd_contribuicoes.py b/l10n_br_sped_efd_contribuicoes/models/sped_efd_contribuicoes.py new file mode 100644 index 00000000..bdf7acd4 --- /dev/null +++ b/l10n_br_sped_efd_contribuicoes/models/sped_efd_contribuicoes.py @@ -0,0 +1,1153 @@ +# -*- coding: utf-8 -*- + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError +from unidecode import unidecode +from datetime import datetime, timedelta +import pytz +import base64 +from sped.efd.pis_cofins.arquivos import ArquivoDigital +from sped.efd.pis_cofins import registros +from sped.efd.pis_cofins.registros import Registro0100 +from sped.efd.pis_cofins.registros import Registro0001 +from sped.efd.pis_cofins.registros import Registro0110 +from sped.efd.pis_cofins.registros import Registro0140 +from sped.efd.pis_cofins.registros import Registro0500 +from sped.efd.pis_cofins.registros import RegistroA001 +from sped.efd.pis_cofins.registros import RegistroA990 +from sped.efd.pis_cofins.registros import RegistroC001 +from sped.efd.pis_cofins.registros import RegistroC010 +from sped.efd.pis_cofins.registros import RegistroC100 +from sped.efd.pis_cofins.registros import RegistroC170 +from sped.efd.pis_cofins.registros import RegistroD001 +from sped.efd.pis_cofins.registros import RegistroD100 +from sped.efd.pis_cofins.registros import RegistroF001 +from sped.efd.pis_cofins.registros import RegistroI001 +from sped.efd.pis_cofins.registros import Registro9001 +from sped.efd.pis_cofins.registros import RegistroM200 +from sped.efd.pis_cofins.registros import RegistroM205 +from sped.efd.pis_cofins.registros import RegistroM210 +from sped.efd.pis_cofins.registros import RegistroM400 +from sped.efd.pis_cofins.registros import RegistroM410 +from sped.efd.pis_cofins.registros import RegistroM600 +from sped.efd.pis_cofins.registros import RegistroM605 +from sped.efd.pis_cofins.registros import RegistroM610 +from sped.efd.pis_cofins.registros import RegistroM800 +from sped.efd.pis_cofins.registros import RegistroM810 +from sped.efd.pis_cofins.registros import RegistroP001 +from sped.efd.pis_cofins.registros import Registro9900 +from sped.efd.pis_cofins.registros import Registro1001 +from sped.efd.pis_cofins.registros import Registro1010 + + +class SpedEfdContribuicoes(models.Model): + _name = "sped.efd.contribuicoes" + _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin'] + _description = "Cria o arquivo para o Sped Contribuicoes Pis/Cofins" + _rec_name = "sped_file_name" + _order = "date_start desc" + + date_start= fields.Date(string='Inicio de') + date_end = fields.Date(string='até') + tipo_escrit = fields.Selection([ + ('0', 'Original'), + ('1', 'Retificadora'), + ], string='Tipo Escrituração', default='0') + num_rec_anterior = fields.Char( + string=u"Número recibo anterior") + ind_nat_pj = fields.Selection([ + ('0', 'Sociedade empresárial geral'), + ('1', 'Sociedade Cooperativa'), + ('2', 'Sujeita ao PIS/Pasep exclusivamente com base na folha de salários'), + ('3', 'Pessoa jurídica participante SCP como sócia ostensiva'), + ('4', 'Sociedade cooperativa participante SCP como sócia ostensiva'), + ('5', 'Sociedade em Conta de Participação - SCP'), + ], string='Indicador natureza pessoa jurídica', default='0') + ind_ativ = fields.Selection([ + ('0', 'Industrial ou equiparado a industrial'), + ('1', 'Prestador de serviços'), + ('2', 'Atividade de comércio'), + ('3', 'Pessoas jurídicas Lei no 9.718, de 1998'), + ('4', 'Atividade imobiliária'), + ('9', 'Outros'), + ], string='Indicador atividade preponderante') + # 0110 + cod_inc_trib = fields.Selection([ + ('1', 'Escrit. oper. incid. exclus. regime não-cumulativo'), + ('2', 'Escrit. oper. incid. exclus. regime cumulativo'), + ('3', 'Escrit. oper. incid. regimes não-cumulativo e cumulativo'), + ], string='Cód. incidência tributária') + ind_apro_cred = fields.Selection([ + ('1', 'Método de Apropriação Direta'), + ('2', 'Método de Rateio Proporcional (Receita Bruta)'), + ], string='Método apropriação de créditos') + cod_tipo_cont = fields.Selection([ + ('1', 'Apuração da Contribuição Exclusivamente a Alíquota Básica'), + ('2', 'Apuração da Contribuição a Alíquotas Específicas (Diferenciadas e/ou por Unidade de Medida de Produto)'), + ], string='Tipo de Contribuição Apurada') + ind_reg_cum = fields.Selection([ + ('1', 'Regime de Caixa –Escrituração consolidada (Registro F500)'), + ('2', 'Regime de Competência -Escrituração consolidada (Registro F550)'), + ('9', 'Regime de Competência -Escrituração detalhada, com base nos registros dos Blocos “A”, “C”, “D” e “F”'), + ], string='Critério de Escrituração e Apuração Adotado') + contas_saida = fields.Many2many( + comodel_name="account.account", + string="Contas Contábeis(Saída/Receita)(0500)", + # domain=[("user_type_id.internal_group", "=", "income")], + ) + contas_entrada = fields.Many2many( + comodel_name="account.account", + string="Contas Contábeis(Aquisição/Custo/Despesa)(0500)", + # domain=[("user_type_id.internal_group", "=", "expense")], + ) + + log_faturamento = fields.Text('Log de Faturamento', copy=False) + company_id = fields.Many2one('res.company', string='Empresa', required=True, + default=lambda self: self.env['res.company']._company_default_get('account.account')) + sped_file = fields.Binary(string=u"Sped") + sped_file_name = fields.Char( + string=u"Arquivo Sped Contribuições") + + def create_file(self): + if self.date_start > self.date_end: + raise UserError('Erro, a data de início é maior que a data de encerramento!') + # self.log_faturamento = 'Gerando arquivo ..
' + if self.date_start and self.date_end: + self.registro0000() + return None + + def versao(self): + #if fields.Datetime.from_string(self.dt_ini) >= datetime.datetime(2018, 1, 1): + # return '012' + return '006' + + def limpa_caracteres(self, data): + if data: + replace = ['|'] + for i in replace: + data = data.replace(i, ' ') + return data + + def limpa_formatacao(self, data): + if data: + replace = ['-', ' ', '(', ')', '/', '.', ':','º'] + for i in replace: + data = data.replace(i, '') + return data + + def junta_pipe(self, registro): + junta = '' + for i in range(1, len(registro._valores)): + junta = junta + '|' + registro._valores[i] + return junta + + def registro0000(self): + arq = ArquivoDigital() + arq._registro_abertura.COD_VER = self.versao() + arq._registro_abertura.TIPO_ESCRIT = 0 # 0 - Original , 1 - Retificadora + arq._registro_abertura.DT_INI = self.date_start + arq._registro_abertura.DT_FIN = self.date_end + arq._registro_abertura.NOME = self.company_id.legal_name + arq._registro_abertura.CNPJ = self.limpa_formatacao(self.company_id.cnpj_cpf) + arq._registro_abertura.UF = self.company_id.state_id.code + arq._registro_abertura.COD_MUN = self.company_id.city_id.ibge_code + arq._registro_abertura.SUFRAMA = '' + arq._registro_abertura.IND_NAT_PJ = '00' # 00 – Pessoa jurídica em geral + arq._registro_abertura.IND_ATIV = '2' # 2 - Atividade de comércio; + if self.company_id.accountant_id: + contabilista = Registro0100() + ctd = self.company_id.accountant_id + if self.company_id.accountant_id.child_ids: + ctd = self.company_id.accountant_id.child_ids[0] + else: + msg_err = 'Cadastre o contador Pessoa Fisica dentro do Contato da Contabilidade' + raise UserError(msg_err) + contador = ctd.name + cod_mun = ctd.city_id.ibge_code + contabilista.NOME = contador + contabilista.CPF = self.limpa_formatacao(ctd.cnpj_cpf) + contabilista.CRC = self.limpa_formatacao(ctd.crc_code) + contabilista.END = ctd.street_name + contabilista.CEP = self.limpa_formatacao(ctd.zip) + contabilista.NUM = ctd.street_number + contabilista.COMPL = ctd.street2 + contabilista.BAIRRO = ctd.district + contabilista.FONE = self.limpa_formatacao(ctd.phone) + contabilista.EMAIL = ctd.email + contabilista.COD_MUN = cod_mun + arq._blocos['0'].add(contabilista) + + reg110 = Registro0110() + reg110.COD_INC_TRIB = self.cod_inc_trib # Cód. ind. da incidência tributária + reg110.IND_APRO_CRED = self.ind_apro_cred # Cód. ind. de método de apropriação de créditos comuns + reg110.COD_TIPO_CONT = self.cod_tipo_cont # Cód. ind. do Tipo de Contribuição Apurada + reg110.IND_REG_CUM = self.ind_reg_cum # Cód. ind. do critério de escrituração e apuração adotado + arq._blocos['0'].add(reg110) + + reg0140 = Registro0140() + reg0140.COD_EST = str(self.company_id.id) + reg0140.NOME = self.company_id.name + reg0140.CNPJ = self.limpa_formatacao(self.company_id.cnpj_cpf) + reg0140.UF = self.company_id.state_id.code + reg0140.IE = self.limpa_formatacao(self.company_id.inscr_est) + reg0140.COD_MUN = cod_mun + reg0140.IM = '' + reg0140.SUFRAMA = '' + arq._blocos['0'].add(reg0140) + + dt = self.date_start + dta_s = '%s-%s-%s' %(str(dt.year),str(dt.month).zfill(2), + str(dt.day).zfill(2)) + dt = self.date_end + dta_e = '%s-%s-%s' %(str(dt.year),str(dt.month).zfill(2), + str(dt.day).zfill(2)) + periodo = 'ie.company_id = %s and \ + date_trunc(\'day\', ie.data_fatura) \ + between \'%s\' and \'%s\'' %(str(self.company_id.id), dta_s, dta_e) + # FORNECEDORES + for item_lista in self.query_registro0150(periodo): + arq.read_registro(self.junta_pipe(item_lista)) + + for item_lista in self.query_registro0190(periodo): + arq.read_registro(self.junta_pipe(item_lista)) + + for item_lista in self.query_registro0200(periodo): + arq.read_registro(self.junta_pipe(item_lista)) + """ # TODO PRECIDO DISTO ?? + # 0205 - ALTERACAO NO ITEM + for item_alt in self.query_registro0205(item_lista.COD_ITEM): + arq.read_registro(self.junta_pipe(item_alt)) + # 0220 - Conversão Unidade Medida + for item_unit in self.query_registro0220(item_lista.COD_ITEM): + arq.read_registro(self.junta_pipe(item_unit)) + """ + + for item_lista in self.query_registro0400(periodo): + arq.read_registro(self.junta_pipe(item_lista)) + + for conta in self.contas_saida: + reg500 = Registro0500() + reg500.DT_ALT = datetime.strptime(conta.write_date, '%Y-%m-%d') + # Conta de resultado + if conta.internal_group == "asset": + reg500.COD_NAT_CC = '01' + elif conta.internal_group == "liability": + reg500.COD_NAT_CC = '02' + elif conta.internal_group == "equity": + reg500.COD_NAT_CC = '03' + elif conta.internal_group == "income": + reg500.COD_NAT_CC = '04' + elif conta.internal_group == "expense": + reg500.COD_NAT_CC = '04' + # TODO Sintetica / Analitica + reg500.IND_CTA = 'S' + # TODO confirmar nivel + reg500.NÍVEL = '5' + reg500.COD_CTA = conta.code + reg500.NOME_CTA = conta.name + arq._blocos['0'].add(reg500) + + for conta in self.contas_entrada: + reg500 = Registro0500() + reg500.DT_ALT = datetime.strptime(conta.write_date, '%Y-%m-%d') + # Conta de Arquisicao/Custo/Despesa + if conta.internal_group == "asset": + reg500.COD_NAT_CC = '01' + elif conta.internal_group == "liability": + reg500.COD_NAT_CC = '02' + elif conta.internal_group == "equity": + reg500.COD_NAT_CC = '03' + elif conta.internal_group == "income": + reg500.COD_NAT_CC = '04' + elif conta.internal_group == "expense": + reg500.COD_NAT_CC = '04' + # TODO Sintetica / Analitica + reg500.IND_CTA = 'S' + # TODO confirmar nivel + reg500.NÍVEL = '5' + reg500.COD_CTA = conta.code + reg500.NOME_CTA = conta.name + arq._blocos['0'].add(reg500) + + query = """ + select distinct + ie.id, ie.state_edoc, ie.issuer + from + l10n_br_fiscal_document as ie + where + %s + and (ie.document_type in ('55','01')) + and (ie.state_edoc in ('autorizada', 'cancelada')) + """ % (periodo) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + cont = 1 + regA001 = RegistroA001() + regA001.IND_MOV = '1' + regA990 = RegistroA990() + regA990.QTD_LIN_A = 1 + regC001 = RegistroC001() + regC001.IND_MOV = '1' + regC010 = RegistroC010() + regC010.CNPJ = self.limpa_formatacao(self.company_id.cnpj_cpf) + regC010.IND_ESCRI = '2' + arq._blocos['C'].add(regC010) + for id in query_resposta: + if id[2] == 'partner' and id[1] == 'cancelada': + continue + regC001.IND_MOV = '0' + # TODO C100 - Notas Fiscais - Feito + for item_lista in self.query_registroC100(id[0]): + arq.read_registro(self.junta_pipe(item_lista)) + # TODO C101 - DIFAL - Feito + #for item_lista in self.query_registroC101(self.fatura): + # arq.read_registro(self.junta_pipe(item_lista)) + + # TODO C110 - Inf. Adiciontal + + # TODO C170 - Itens Nota Fiscal de Compras = Fazendo + for item_lista in self.query_registroC170(id[0]): + arq.read_registro(self.junta_pipe(item_lista)) + + # TODO BLOCO D - prestações ou contratações de serviços + # de comunicação, transporte interestadual e intermunicipa + # TODO D100 - Periodo Apuracao + + query = """ + select distinct + ie.id, ie.state_edoc + from + l10n_br_fiscal_document as ie + where + %s + and (ie.document_type in ('57','67')) + and ((ie.amount_pis_value > 0) or (ie.amount_cofins_value > 0)) + and (ie.state_edoc in ('autorizada')) + """ % (periodo) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + cont = 1 + registro_D001 = RegistroD001() + if query_resposta: + registro_D001.IND_MOV = '0' + else: + registro_D001.IND_MOV = '1' + + # TODO PAREI AQUI + """ + resposta_cte = self.env['invoice.eletronic'].search([ + ('model','in',('57','67')), + ('state', '=','done'), + ('data_fatura','>=',g_intervalo[0]), + ('data_fatura','<=',g_intervalo[1]), + ]) + """ + #for cte in resposta_cte: + # TODO D100 - Documentos Transporte + #TODO DEIXAMOS FORA POIS NAO EXISTE NO ATS ADMIN + #for item_lista in self.query_registroD100(cte.invoice_id.id): + #arq.read_registro(self.junta_pipe(item_lista)) + + # TODO D190 - Totalizacao por CST + #for item_lista in self.query_registroD190(cte.invoice_id.id): + # arq.read_registro(self.junta_pipe(item_lista)) + regF001 = RegistroF001() + regF001.IND_MOV = '1' + + #regF990 = RegistroF990() + #regF990.QTD_LIN_F = 1 + #arq._blocos['F'].add(regF001) + + regI001 = RegistroI001() + regI001.IND_MOV = '1' + #arq._blocos['I'].add(regI990) + + # é gerados pelo VALIDADOR + for item_lista in self.query_registroM200(periodo): + arq.read_registro(self.junta_pipe(item_lista)) + + for item_lista in self.query_registroM400(periodo): + arq.read_registro(self.junta_pipe(item_lista)) + for item_lista in self.query_registroM410(item_lista.CST_PIS, periodo): + arq.read_registro(self.junta_pipe(item_lista)) + + # é gerados pelo VALIDADOR + for item_lista in self.query_registroM600(periodo): + arq.read_registro(self.junta_pipe(item_lista)) + + + """ + regM800 = RegistroM800() + regM800.CST_COFINS = '06' + #TODO VL_TOT_REC CARREGAR VALOR. + regM800.VL_TOT_REC = '0' + regM800.COD_CTA = '1.1.06.11.00.00' + arq._blocos['M'].add(regM800) + """ + for item_lista in self.query_registroM800(periodo): + arq.read_registro(self.junta_pipe(item_lista)) + for item_lista in self.query_registroM810(item_lista.CST_COFINS, periodo): + arq.read_registro(self.junta_pipe(item_lista)) + + regP001 = RegistroP001() + regP001.IND_MOV = '1' + + #import pudb;pu.db + registro_1001 = Registro1001() + registro_1001.IND_MOV = '1' + #arq._blocos['1'].add(registro_1001) + arq.prepare() + self.sped_file_name = 'PisCofins-%s_%s.txt' % ( + str(dt.month).zfill(2), str(dt.year)) + #arqxx = open('/opt/odoo/novo_arquivo.txt', 'w') + #arqxx.write(arq.getstring()) + #arqxx.close() + self.sped_file = base64.encodestring(bytes(arq.getstring(), 'iso-8859-1')) + + def query_registro0150(self, periodo): + query = """ + select distinct + ie.partner_id + from + invoice_eletronic ie + where + %s + and (ie.model in ('55','01','57','67')) + and (ie.state = 'done') + """ % (periodo) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + for id in query_resposta: + resposta_participante = self.env['res.partner'].browse(id[0]) + registro_0150 = registros.Registro0150() + registro_0150.COD_PART = str(resposta_participante.id) + registro_0150.NOME = resposta_participante.legal_name or resposta_participante.name + cod_pais = resposta_participante.country_id.bc_code + registro_0150.COD_PAIS = cod_pais + cpnj_cpf = self.limpa_formatacao(resposta_participante.cnpj_cpf) + cod_mun = '%s%s' %(resposta_participante.state_id.ibge_code, resposta_participante.city_id.ibge_code) + if cod_pais == '01058': + registro_0150.COD_MUN = self.formata_cod_municipio(cod_mun) + if len(cpnj_cpf) == 11: + registro_0150.CPF = cpnj_cpf + else: + registro_0150.CNPJ = cpnj_cpf + registro_0150.IE = self.limpa_formatacao(resposta_participante.inscr_est) + else: + registro_0150.COD_MUN = '9999999' + registro_0150.SUFRAMA = self.limpa_formatacao(resposta_participante.suframa) + if resposta_participante.street: + registro_0150.END = resposta_participante.street.strip() + if resposta_participante.number: + registro_0150.NUM = resposta_participante.number.strip() + if resposta_participante.street2: + registro_0150.COMPL = resposta_participante.street2.strip() + if resposta_participante.district: + registro_0150.BAIRRO = resposta_participante.district.strip() + lista.append(registro_0150) + + return lista + + def query_registro0190(self, periodo): + query = """ + select distinct + substr(UPPER(pu.name), 1,6) + , UPPER(pu.l10n_br_description) + from + invoice_eletronic as ie + inner join + invoice_eletronic_item as det + on ie.id = det.invoice_eletronic_id + inner join product_product pp + on pp.id = det.product_id + inner join product_template pt + on pt.id = pp.product_tmpl_id + inner join + uom_uom pu + on pu.id = det.uom_id or pu.id = pt.uom_id + where + %s + and (ie.model in ('55','01')) + and ie.state = 'done' + and ie.emissao_doc = '2' + order by 1 + """ % (periodo) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + lista_un = [] + un = '' + for id in query_resposta: + registro_0190 = registros.Registro0190() + unidade = '' + if id[0].find('-') != -1: + unidade = id[0][:id[0].find('-')] + else: + unidade = id[0] + unidade = unidade[:6] + if un == unidade: + continue + lista_un.append(unidade) + registro_0190.UNID = unidade + desc = id[1] + if not desc: + msg_err = 'Unidade de medida sem descricao - Un %s.' %(unidade) + raise UserError(msg_err) + registro_0190.DESCR = desc.strip() + lista.append(registro_0190) + un = unidade + return lista + + def query_registro0200(self, periodo): + query = """ + select distinct + det.product_id + from + invoice_eletronic as ie + inner join + invoice_eletronic_item as det + on ie.id = det.invoice_eletronic_id + where + %s + and (ie.model in ('55','01')) + and ie.state = 'done' + """ % (periodo) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + #hash = {} + lista = [] + lista_item = [] + cont = 1 + for resposta in query_resposta: + resposta_produto = self.env['product.product'].browse(resposta[0]) + if not resposta_produto: + continue + lista_item.append(resposta_produto.id) + registro_0200 = registros.Registro0200() + cprod = resposta_produto.default_code + registro_0200.COD_ITEM = cprod + desc_item = resposta_produto.name.strip() + try: + desc_item = desc_item.encode('iso-8859-1') + desc_item = resposta_produto.name.strip() + except: + desc_item = unidecode(desc_item) + registro_0200.DESCR_ITEM = desc_item + if resposta_produto.barcode != resposta_produto.default_code: + registro_0200.COD_BARRA = resposta_produto.barcode + if resposta_produto.uom_id.name.find('-') != -1: + unidade = resposta_produto.uom_id.name[:resposta_produto.uom_id.name.find('-')] + else: + unidade = resposta_produto.uom_id.name + unidade = unidade.strip() + unidade = unidade.upper() + unidade = unidade[:6] + registro_0200.UNID_INV = unidade[:6] + registro_0200.TIPO_ITEM = resposta_produto.l10n_br_sped_type + registro_0200.COD_NCM = self.limpa_formatacao(resposta_produto.fiscal_classification_id.code) + lista.append(registro_0200) + return lista + + def query_registro0400(self, periodo): + query = """ + select distinct + d.fiscal_position_id + from + account_invoice as d + inner join + invoice_eletronic as ie + on ie.invoice_id = d.id + left join + br_account_fiscal_document fd + on fd.id = d.product_document_id + where + %s + and (ie.model in ('55','01')) + and ie.state in ('done') + and d.fiscal_position_id is not null + """ % (periodo) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + for resposta in query_resposta: + resposta_nat = self.env['account.fiscal.position'].browse(resposta[0]) + registro_0400 = registros.Registro0400() + registro_0400.COD_NAT = str(resposta_nat.id) + registro_0400.DESCR_NAT = resposta_nat.natureza_operacao + lista.append(registro_0400) + return lista + + def transforma_valor(self, valor): + valor = ("%.2f" % (float(valor))) + return str(valor).replace('.', ',') + + def query_registroC100(self, doc): + lista = [] + nfe_ids = self.env['invoice.eletronic'].browse(doc) + for nf in nfe_ids: + if (nf.state == 'done') and (nf.model == '55'): + cancel = False + registro_c100 = registros.RegistroC100() + if nf.tipo_operacao == 'entrada': + registro_c100.IND_OPER = '0' + else: + registro_c100.IND_OPER = '1' + if nf.emissao_doc == '1': + registro_c100.IND_EMIT = '0' + else: + registro_c100.IND_EMIT = '1' + registro_c100.COD_MOD = nf.model + if nf.state == 'cancel': + registro_c100.COD_SIT = '02' + cancel = True + else: + registro_c100.COD_SIT = '00' + registro_c100.SER = nf.serie_documento + registro_c100.CHV_NFE = nf.chave_nfe + registro_c100.NUM_DOC = self.limpa_formatacao(str(nf.numero)) + if not cancel: + registro_c100.DT_DOC = nf.data_emissao + if nf.data_fatura: + registro_c100.DT_E_S = nf.data_fatura + else: + registro_c100.DT_E_S = nf.data_emissao + if nf.metodo_pagamento: + registro_c100.IND_PGTO = nf.metodo_pagamento + registro_c100.VL_MERC = self.transforma_valor(nf.valor_bruto) + registro_c100.IND_FRT = str(nf.modalidade_frete) + registro_c100.VL_FRT = self.transforma_valor(nf.valor_frete) + registro_c100.VL_SEG = self.transforma_valor(nf.valor_seguro) + registro_c100.VL_OUT_DA = self.transforma_valor(nf.valor_despesas) + registro_c100.VL_DESC = self.transforma_valor(nf.valor_desconto) + registro_c100.VL_DOC = self.transforma_valor(nf.valor_final) + registro_c100.VL_BC_ICMS = self.transforma_valor(nf.valor_bc_icms) + registro_c100.VL_ICMS = self.transforma_valor(nf.valor_icms) + registro_c100.VL_BC_ICMS_ST = self.transforma_valor(nf.valor_bc_icmsst) + registro_c100.VL_ICMS_ST = self.transforma_valor(nf.valor_icmsst) + registro_c100.VL_IPI = self.transforma_valor(nf.valor_ipi) + registro_c100.VL_PIS = self.transforma_valor(nf.valor_pis) + registro_c100.VL_COFINS = self.transforma_valor(nf.valor_cofins) + registro_c100.COD_PART = str(nf.partner_id.id) + lista.append(registro_c100) + return lista + + def query_registroC170(self, doc): + lista = [] + nfe_line = self.env['invoice.eletronic.item'].search([ + ('invoice_eletronic_id','=', doc), + ], order='num_item') + n_item = 1 + for item in nfe_line: + registro_c170 = registros.RegistroC170() + if item.num_item > 1: + registro_c170.NUM_ITEM = str(item.num_item) + else: + registro_c170.NUM_ITEM = str(n_item) # str(item.num_item_xml or n_item) + cprod = item.product_id.default_code #.replace('.','') + registro_c170.COD_ITEM = cprod + registro_c170.DESCR_COMPL = self.limpa_caracteres(item.name.strip()) + registro_c170.QTD = self.transforma_valor(item.quantidade) + if item.uom_id.name.find('-') != -1: + unidade = item.uom_id.name[:item.uom_id.name.find('-')] + else: + unidade = item.uom_id.name + registro_c170.UNID = unidade[:6] + registro_c170.VL_DESC = self.transforma_valor(item.desconto) + registro_c170.VL_ITEM = self.transforma_valor(item.valor_bruto) + if item.cfop in ['5922', '6922']: + registro_c170.IND_MOV = '1' + else: + registro_c170.IND_MOV = '0' + try: + registro_c170.CST_ICMS = '%s%s' %(str(item.origem), str(item.icms_cst)) + except: + msg_err = 'Sem CST na Fatura %s.
' %(str(resposta.number or resposta.id)) + #raise UserError(msg_err) + self.log_faturamento += msg_err + if item.cfop: + registro_c170.CFOP = str(item.cfop) + else: + registro_c170.CFOP = '0000' + #if r_nfe.id == 407: + # import pudb;pu.db + registro_c170.COD_NAT = str(item.invoice_eletronic_id.fiscal_position_id.id) + registro_c170.VL_BC_ICMS = self.transforma_valor(item.icms_base_calculo) + registro_c170.ALIQ_ICMS = '0' + registro_c170.ALIQ_ICMS = self.transforma_valor(item.icms_aliquota) + + registro_c170.VL_ICMS = self.transforma_valor(item.icms_valor) + registro_c170.VL_BC_ICMS_ST = self.transforma_valor(item.icms_st_base_calculo) + if item.icms_st_aliquota: + registro_c170.ALIQ_ST = self.transforma_valor(item.icms_st_aliquota) + registro_c170.VL_ICMS_ST = self.transforma_valor(item.icms_st_valor) + # TODO incluir na empresa o IND_APUR + registro_c170.IND_APUR = '0' + registro_c170.CST_IPI = item.ipi_cst + registro_c170.VL_BC_IPI = self.transforma_valor(item.ipi_base_calculo) + if item.ipi_aliquota: + registro_c170.ALIQ_IPI = self.transforma_valor(item.ipi_aliquota) + registro_c170.VL_IPI = self.transforma_valor(item.ipi_valor) + registro_c170.CST_PIS = item.pis_cst + registro_c170.VL_BC_PIS = self.transforma_valor(item.pis_base_calculo) + registro_c170.ALIQ_PIS = self.transforma_valor(item.pis_aliquota) + #registro_c170.QUANT_BC_PIS = self.transforma_valor( + registro_c170.VL_PIS = self.transforma_valor(item.pis_valor) + registro_c170.CST_COFINS = item.cofins_cst + registro_c170.VL_BC_COFINS = self.transforma_valor(item.cofins_base_calculo) + registro_c170.ALIQ_COFINS = self.transforma_valor(item.cofins_aliquota) + #registro_c170.QUANT_BC_COFINS = self.transforma_valor( + registro_c170.VL_COFINS = self.transforma_valor(item.cofins_valor) + n_item += 1 + + lista.append(registro_c170) + + return lista + + # transporte + #TODO DEIXAMOS FORA POIS NAO EXISTE NO ATS ADMIN + def query_registroD100(self, doc): + lista = [] + resposta_cte = self.env['account.invoice'].browse(fatura) + for resposta in resposta_cte: + cte = self.env['invoice.eletronic'].search([('invoice_id','=',fatura)]) + registro_d100 = registros.RegistroD100() + registro_d100.IND_OPER = '0' # Aquisicao + registro_d100.IND_EMIT = '1' # Terceiros + registro_d100.COD_PART = str(resposta.partner_id.id) + registro_d100.COD_MOD = str(resposta.nfe_modelo) # or resposta_nfe.product_document_id.code).zfill(2) + #if cte.tp_emiss_cte == '1': + registro_d100.COD_SIT = '00' + """ + elif cte.tp_emiss_cte == '2': + registro_d100.COD_SIT = '01' + elif cte.tp_emiss_cte == '3': + registro_d100.COD_SIT = '02' + elif cte.tp_emiss_cte == '4': + registro_d100.COD_SIT = '03' + elif cte.tp_emiss_cte == '5': + registro_d100.COD_SIT = '04' + elif cte.tp_emiss_cte == '6': + registro_d100.COD_SIT = '05' + elif cte.tp_emiss_cte == '7': + registro_d100.COD_SIT = '06' + elif cte.tp_emiss_cte == '8': + registro_d100.COD_SIT = '07' + elif cte.tp_emiss_cte == '9': + registro_d100.COD_SIT = '08' + """ + registro_d100.SER = resposta.nfe_serie[:3] # resposta.product_serie_id.code + if resposta.nfe_chave: + if len(resposta.nfe_chave) != 44: + msg_err = 'Tamanho da Chave NFe invalida - Fatura %s.' %(str(resposta.number or resposta.id)) + #raise UserError(msg_err) + self.log_faturamento += msg_err + registro_d100.CHV_CTE = str(resposta.nfe_chave) # or resposta_nfe.chave_nfe + registro_d100.NUM_DOC = self.limpa_formatacao(str(cte.numero)) # or resposta_nfe.numero)) + registro_d100.DT_A_P = cte.data_fatura or resposta.date_invoice + registro_d100.DT_DOC = cte.data_emissao or resposta.date_invoice + #registro_d100.TP_CT-e = '0' # NORMAL + registro_d100.VL_DOC = self.transforma_valor(resposta.amount_total) + registro_d100.VL_DESC = self.transforma_valor(resposta.total_desconto) + registro_d100.IND_FRT = '1' # Destinatario + registro_d100.VL_SERV = self.transforma_valor(resposta.amount_total) + registro_d100.VL_BC_ICMS = self.transforma_valor(resposta.icms_base) + registro_d100.VL_ICMS = self.transforma_valor(resposta.icms_value) + registro_d100.VL_NT = '0' + registro_d100.COD_INF = '' + registro_d100.COD_MUN_ORIG = cte.cod_mun_ini + registro_d100.COD_MUN_DEST = cte.cod_mun_fim + lista.append(registro_d100) + + return lista + + """ SOMENTE DE SAIDA + # transporte - detalhe + def query_registroD110(self, fatura): + lista = [] + resposta = self.env['account.invoice'].search([ + ('nfe_modelo','in',('57','67')), + ('state', 'in',('open','paid')) + ]) + item = 1 + for itens in resposta.invoice_line_ids: + registro_d110 = registros.RegistroD110() + registro_d110.NUM_ITEM = str(item) # + registro_d110.COD_ITEM = itens.product_id.default_code # Terceiros + registro_d110.VL_SERV = self.transforma_valor(itens.price_subtotal) + registro_d110.VL_OUT = '0' + item += 1 + + # transporte - complemento + def query_registroD120(self, fatura): + lista = [] + resposta = self.env['account.invoice'].search([ + ('nfe_modelo','in',('57','67')), + ('state', 'in',('open','paid')) + ]) + item = 1 + for itens in resposta.invoice_line_ids: + registro_d110 = registros.RegistroD110() + registro_d110.NUM_ITEM = str(item) # + registro_d110.COD_ITEM = itens.product_id.default_code # Terceiros + registro_d110.VL_SERV = self.transforma_valor(itens.price_subtotal) + registro_d110.VL_OUT = '0' + item += 1 + """ + + # transporte - analitico + def query_registroD190(self, fatura): + query = """ + select distinct + pt.origin || dl.icms_cst_normal, + cfop.code, + COALESCE(at.amount, 0.0) as ALIQUOTA , + sum(dl.price_subtotal+dl.outras_despesas) as VL_OPR, + sum(dl.icms_base_calculo) as VL_BC_ICMS, + sum(dl.icms_valor) as VL_ICMS, + sum(dl.icms_st_base_calculo) as VL_BC_ICMS_ST, + sum(dl.icms_st_valor) as VL_ICMS_ST, + case when (dl.icms_aliquota_reducao_base > 0) then + sum((dl.price_subtotal+dl.outras_despesas)-dl.icms_base_calculo) else 0 end as VL_RED_BC, + sum(dl.ipi_valor) as VL_IPI + from + account_invoice as d + inner join + account_invoice_line dl + on dl.invoice_id = d.id + left join + invoice_eletronic il + on il.invoice_id = d.id + left join + account_tax at + on at.id = dl.tax_icms_id + left join + br_account_fiscal_document fd + on fd.id = d.product_document_id + inner join + account_fiscal_position fp + on d.fiscal_position_id = fp.id + inner join + br_account_cfop cfop + on dl.cfop_id = cfop.id + inner join + product_product pp + on pp.id = dl.product_id + inner join + product_template pt + on pt.id = pp.product_tmpl_id + where + d.nfe_modelo in ('57','67') + and d.state in ('open','paid') + and ((il.valor_pis > 0) or (il.valor_cofins > 0)) + and d.fiscal_position_id is not null + and ((il.state is null) or (il.state = 'done')) + and d.id = '%s' + group by + dl.icms_aliquota_reducao_base, + dl.icms_cst_normal, + cfop.code, + at.amount, + pt.origin + order by 1,2,3 + """ % (fatura) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + cont = 1 + for id in query_resposta: + registro_d190 = registros.RegistroD190() + registro_d190.CST_ICMS = id[0] + registro_d190.CFOP = id[1] + registro_d190.ALIQ_ICMS = self.transforma_valor(id[2]) + registro_d190.VL_OPR = self.transforma_valor(id[3]) + registro_d190.VL_BC_ICMS = self.transforma_valor(id[4]) + registro_d190.VL_ICMS = self.transforma_valor(id[5]) + registro_d190.VL_RED_BC = self.transforma_valor(id[8]) + registro_d190.COD_OBS = '' + + lista.append(registro_d190) + + return lista + + def query_registroM200(self, periodo): + query = """ + select + sum(det.valor_liquido), + det.pis_aliquota, + sum(det.pis_valor) + from + invoice_eletronic as ie + inner join + invoice_eletronic_item as det + on ie.id = det.invoice_eletronic_id + where + %s + and (ie.model in ('55','01')) + and ie.state = 'done' + and det.pis_valor > 0 + and (det.cofins_cst in ('01','02','03')) + group by det.pis_aliquota + """ % (periodo) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + lista_item = [] + cont = 1 + for resposta in query_resposta: + regM200 = RegistroM200() + regM200.VL_TOT_CONT_NC_PER = '0' + regM200.VL_TOT_CRED_DESC = '0' + regM200.VL_TOT_CRED_DESC_ANT = '0' + regM200.VL_TOT_CONT_NC_DEV = '0' + regM200.VL_RET_NC = '0' + regM200.VL_OUT_DED_NC = '0' + regM200.VL_CONT_NC_REC = '0' + regM200.VL_TOT_CONT_CUM_PER = resposta[2] + regM200.VL_RET_CUM = '0' + regM200.VL_OUT_DED_CUM = '0' + regM200.VL_CONT_CUM_REC = resposta[2] + regM200.VL_TOT_CONT_REC = resposta[2] + lista.append(regM200) + + regM205 = RegistroM205() + regM205.NUM_CAMPO = '12' + regM205.COD_REC = '810902' + regM205.VL_DEBITO = resposta[2] + lista.append(regM205) + + regM210 = RegistroM210() + regM210.COD_CONT = '51' + regM210.VL_REC_BRT = self.transforma_valor(resposta[0]) + regM210.VL_BC_CONT = self.transforma_valor(resposta[0]) + regM210.VL_AJUS_ACRES_BC_PIS = '0' + regM210.VL_AJUS_REDUC_BC_PIS = '0' + regM210.VL_BC_CONT_AJUS = self.transforma_valor(resposta[0]) + regM210.ALIQ_PIS = self.transforma_valor(resposta[1]) + regM210.QUANT_BC_PIS = '0' + regM210.ALIQ_PIS_QUANT = '0' + regM210.VL_CONT_APUR = self.transforma_valor(resposta[2]) + regM210.VL_AJUS_ACRES = '0' + regM210.VL_AJUS_REDUC = '0' + regM210.VL_CONT_DIFER = '0' + regM210.VL_CONT_DIFER_ANT = '0' + regM210.VL_CONT_PER = self.transforma_valor(resposta[2]) + lista.append(regM210) + + return lista + + """ + + + """ + + def query_registroM400(self, periodo): + query = """ + select + det.pis_cst, + sum(det.valor_liquido) + from + invoice_eletronic as ie + inner join + invoice_eletronic_item as det + on ie.id = det.invoice_eletronic_id + where + %s + and (ie.model in ('55','01')) + and ie.state = 'done' + and (det.pis_cst in ('04','06','07','08','09')) + group by det.pis_cst + """ % (periodo) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + lista_item = [] + cont = 1 + for resposta in query_resposta: + registro_M400 = registros.RegistroM400() + registro_M400.CST_PIS = resposta[0] + registro_M400.VL_TOT_REC = self.transforma_valor(resposta[1]) + registro_M400.COD_CTA = '1.1.06.11.00.00' + lista.append(registro_M400) + return lista + + def query_registroM410(self, cst_pis, periodo): + query = """ + select distinct + substr(pr.name, 1,3), + sum(det.valor_liquido) + from + invoice_eletronic as ie + inner join + invoice_eletronic_item as det + on ie.id = det.invoice_eletronic_id + inner join + product_product as pp + on pp.id = det.product_id + inner join + product_template as pt + on pt.id = pp.product_tmpl_id + inner join + product_category as pc + on pc.id = pt.categ_id + inner join + product_category as pr + on pr.id = pc.parent_id + where + %s + and (ie.model in ('55','01')) + and ie.state = 'done' + and (det.pis_cst = \'%s\') + group by substr(pr.name, 1,3) + """ % (periodo, cst_pis) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + lista_item = [] + cont = 1 + for resposta in query_resposta: + registro_M410 = registros.RegistroM410() + registro_M410.NAT_REC = resposta[0] + registro_M410.VL_REC = self.transforma_valor(resposta[1]) + registro_M410.COD_CTA = '1.1.06.11.00.00' + lista.append(registro_M410) + return lista + + def query_registroM600(self, periodo): + query = """ + select + sum(det.valor_liquido), + det.cofins_aliquota, + sum(det.cofins_valor) + from + invoice_eletronic as ie + inner join + invoice_eletronic_item as det + on ie.id = det.invoice_eletronic_id + where + %s + and (ie.model in ('55','01')) + and ie.state = 'done' + and (det.cofins_cst in ('01','02','03')) + group by det.cofins_aliquota + """ % (periodo) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + lista_item = [] + cont = 1 + for resposta in query_resposta: + regM600 = RegistroM600() + regM600.VL_TOT_CONT_NC_PER = '0' + regM600.VL_TOT_CRED_DESC = '0' + regM600.VL_TOT_CRED_DESC_ANT = '0' + regM600.VL_TOT_CONT_NC_DEV = '0' + regM600.VL_RET_NC = '0' + regM600.VL_OUT_DED_NC = '0' + regM600.VL_CONT_NC_REC = '0' + regM600.VL_TOT_CONT_CUM_PER = self.transforma_valor(resposta[2]) + regM600.VL_RET_CUM = '0' + regM600.VL_OUT_DED_CUM = '0' + regM600.VL_CONT_CUM_REC = self.transforma_valor(resposta[2]) + regM600.VL_TOT_CONT_REC = self.transforma_valor(resposta[2]) + lista.append(regM600) + + regM605 = RegistroM605() + regM605.NUM_CAMPO = '12' + regM605.COD_REC = '217201' + regM605.VL_DEBITO = self.transforma_valor(resposta[2]) + lista.append(regM605) + + regM610 = RegistroM610() + regM610.COD_CONT = '51' + regM610.VL_REC_BRT = self.transforma_valor(resposta[0]) + regM610.VL_BC_CONT = self.transforma_valor(resposta[0]) + regM610.VL_AJUS_ACRES_BC_COFINS = '0' + regM610.VL_AJUS_REDUC_BC_COFINS = '0' + regM610.VL_BC_CONT_AJUS = self.transforma_valor(resposta[0]) + regM610.ALIQ_COFINS = self.transforma_valor(resposta[1]) + regM610.QUANT_BC_COFINS = '0' + regM610.ALIQ_COFINS_QUANT = '0' + regM610.VL_CONT_APUR = self.transforma_valor(resposta[2]) + regM610.VL_AJUS_ACRES = '0' + regM610.VL_AJUS_REDUC = '0' + regM610.VL_CONT_DIFER = '0' + regM610.VL_CONT_DIFER_ANT = '0' + regM610.VL_CONT_PER = self.transforma_valor(resposta[2]) + lista.append(regM610) + return lista + + def query_registroM800(self, periodo): + query = """ + select + det.cofins_cst, + sum(det.valor_liquido) + from + invoice_eletronic as ie + inner join + invoice_eletronic_item as det + on ie.id = det.invoice_eletronic_id + where + %s + and (ie.model in ('55','01')) + and ie.state = 'done' + and (det.cofins_cst in ('04','06','07','08','09')) + group by det.cofins_cst + """ % (periodo) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + lista_item = [] + cont = 1 + for resposta in query_resposta: + registro_M800 = registros.RegistroM800() + registro_M800.CST_COFINS = resposta[0] + registro_M800.VL_TOT_REC = self.transforma_valor(resposta[1]) + registro_M800.COD_CTA = '1.1.06.11.00.00' + lista.append(registro_M800) + return lista + + def query_registroM810(self, cofins_cst, periodo): + query = """ + select + substr(pr.name,1,3), + sum(det.valor_liquido) + from + invoice_eletronic as ie + inner join + invoice_eletronic_item as det + on ie.id = det.invoice_eletronic_id + inner join + product_product as pp + on pp.id = det.product_id + inner join + product_template as pt + on pt.id = pp.product_tmpl_id + inner join + product_category as pc + on pc.id = pt.categ_id + inner join + product_category as pr + on pr.id = pc.parent_id + where + %s + and (ie.model in ('55','01')) + and ie.state = 'done' + and (det.cofins_cst = \'%s\') + group by substr(pr.name,1,3) + """ % (periodo, cofins_cst) + self._cr.execute(query) + query_resposta = self._cr.fetchall() + lista = [] + lista_item = [] + cont = 1 + for resposta in query_resposta: + registro_M810 = registros.RegistroM810() + cod_nat = resposta[0] + registro_M810.NAT_REC = cod_nat[:3] + registro_M810.VL_REC = self.transforma_valor(resposta[1]) + registro_M810.COD_CTA = '1.1.06.11.00.00' + lista.append(registro_M810) + return lista diff --git a/l10n_br_sped_efd_contribuicoes/security/ir.model.access.csv b/l10n_br_sped_efd_contribuicoes/security/ir.model.access.csv new file mode 100644 index 00000000..bc2aaa89 --- /dev/null +++ b/l10n_br_sped_efd_contribuicoes/security/ir.model.access.csv @@ -0,0 +1,2 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +access_br_sped_efd_contribuicoes,access_br_sped_efd_contribuicoes,model_sped_efd_contribuicoes,base.group_user,1,1,1,1 diff --git a/l10n_br_sped_efd_contribuicoes/views/sped_contribuicoes_view.xml b/l10n_br_sped_efd_contribuicoes/views/sped_contribuicoes_view.xml new file mode 100644 index 00000000..e7e0f1d5 --- /dev/null +++ b/l10n_br_sped_efd_contribuicoes/views/sped_contribuicoes_view.xml @@ -0,0 +1,64 @@ + + + + SPED Contribuicoes + sped.efd.contribuicoes + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + + view_sped_efd_contribuicoes_tree + sped.efd.contribuicoes + + + + + + + + + + + + + + Sped Contruibuições(PIS/COFINS) + sped.efd.contribuicoes + form + tree,form + + + +
From f175d1fe6e364edd53ec9982e29b3eba3cabdefa Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Wed, 15 Feb 2023 14:27:08 -0300 Subject: [PATCH 002/609] =?UTF-8?q?Migrado=20SQL=20para=20localiza=C3=A7?= =?UTF-8?q?=C3=A3o=20l10n-brazil=2014.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/sped_efd_contribuicoes.py | 197 +++++++++--------- .../views/sped_contribuicoes_view.xml | 75 ++++--- 2 files changed, 141 insertions(+), 131 deletions(-) diff --git a/l10n_br_sped_efd_contribuicoes/models/sped_efd_contribuicoes.py b/l10n_br_sped_efd_contribuicoes/models/sped_efd_contribuicoes.py index bdf7acd4..7cada7d9 100644 --- a/l10n_br_sped_efd_contribuicoes/models/sped_efd_contribuicoes.py +++ b/l10n_br_sped_efd_contribuicoes/models/sped_efd_contribuicoes.py @@ -53,8 +53,12 @@ class SpedEfdContribuicoes(models.Model): ('0', 'Original'), ('1', 'Retificadora'), ], string='Tipo Escrituração', default='0') + cod_receita_pis = fields.Char( + string=u"Código receita Pis(Débito DCTF)", default="810902") + cod_receita_cofins = fields.Char( + string=u"Código receita Cofins(Débito DCTF)", default="217201") num_rec_anterior = fields.Char( - string=u"Número recibo anterior") + string=u"Número recibo anterior") ind_nat_pj = fields.Selection([ ('0', 'Sociedade empresárial geral'), ('1', 'Sociedade Cooperativa'), @@ -336,14 +340,6 @@ def registro0000(self): registro_D001.IND_MOV = '1' # TODO PAREI AQUI - """ - resposta_cte = self.env['invoice.eletronic'].search([ - ('model','in',('57','67')), - ('state', '=','done'), - ('data_fatura','>=',g_intervalo[0]), - ('data_fatura','<=',g_intervalo[1]), - ]) - """ #for cte in resposta_cte: # TODO D100 - Documentos Transporte #TODO DEIXAMOS FORA POIS NAO EXISTE NO ATS ADMIN @@ -874,22 +870,22 @@ def query_registroD190(self, fatura): def query_registroM200(self, periodo): query = """ - select - sum(det.valor_liquido), - det.pis_aliquota, - sum(det.pis_valor) + select + sum(det.pis_base), + det.pis_percent, + sum(det.pis_value) from - invoice_eletronic as ie + l10n_br_fiscal_document as ie inner join - invoice_eletronic_item as det - on ie.id = det.invoice_eletronic_id + l10n_br_fiscal_document_line as det + on ie.id = det.document_id where %s - and (ie.model in ('55','01')) - and ie.state = 'done' - and det.pis_valor > 0 - and (det.cofins_cst in ('01','02','03')) - group by det.pis_aliquota + and (ie.document_type in ('55','01')) + and (ie.state_edoc = 'autorizada') + and det.pis_value > 0 + and (det.pis_cst_code in ('01','02','03')) + group by det.pis_percent """ % (periodo) self._cr.execute(query) query_resposta = self._cr.fetchall() @@ -914,7 +910,7 @@ def query_registroM200(self, periodo): regM205 = RegistroM205() regM205.NUM_CAMPO = '12' - regM205.COD_REC = '810902' + regM205.COD_REC = self.cod_receita_pis regM205.VL_DEBITO = resposta[2] lista.append(regM205) @@ -946,19 +942,23 @@ def query_registroM200(self, periodo): def query_registroM400(self, periodo): query = """ select - det.pis_cst, - sum(det.valor_liquido) + det.pis_cst_code, + sum(det.pis_base), + aa.code AS cod_cta from - invoice_eletronic as ie + l10n_br_fiscal_document as ie inner join - invoice_eletronic_item as det - on ie.id = det.invoice_eletronic_id + l10n_br_fiscal_document_line as det + on ie.id = det.document_id + inner join + account.account AS aa + on aa.id det.account_id where %s - and (ie.model in ('55','01')) - and ie.state = 'done' - and (det.pis_cst in ('04','06','07','08','09')) - group by det.pis_cst + and (ie.document_type in ('55','01')) + and (ie.state_edoc = 'autorizada') + and (det.pis_cst_code in ('04','06','07','08','09')) + group by det.pis_cst_code, aa.code """ % (periodo) self._cr.execute(query) query_resposta = self._cr.fetchall() @@ -969,38 +969,31 @@ def query_registroM400(self, periodo): registro_M400 = registros.RegistroM400() registro_M400.CST_PIS = resposta[0] registro_M400.VL_TOT_REC = self.transforma_valor(resposta[1]) - registro_M400.COD_CTA = '1.1.06.11.00.00' + registro_M400.COD_CTA = resposta[2] lista.append(registro_M400) return lista def query_registroM410(self, cst_pis, periodo): + # TODO validar isso query = """ select distinct - substr(pr.name, 1,3), - sum(det.valor_liquido) + det.ncm_id, + sum(det.valor_liquido), + aa.code AS cod_cta from - invoice_eletronic as ie - inner join - invoice_eletronic_item as det - on ie.id = det.invoice_eletronic_id - inner join - product_product as pp - on pp.id = det.product_id - inner join - product_template as pt - on pt.id = pp.product_tmpl_id + l10n_br_fiscal_document as ie inner join - product_category as pc - on pc.id = pt.categ_id + l10n_br_fiscal_document_line as det + on ie.id = det.document_id inner join - product_category as pr - on pr.id = pc.parent_id + account.account AS aa + on aa.id det.account_id where %s - and (ie.model in ('55','01')) - and ie.state = 'done' - and (det.pis_cst = \'%s\') - group by substr(pr.name, 1,3) + and (ie.document_type in ('55','01')) + and (ie.state_edoc = 'autorizada') + and (det.pis_cst_code = \'%s\') + group by det.ncm_id """ % (periodo, cst_pis) self._cr.execute(query) query_resposta = self._cr.fetchall() @@ -1008,30 +1001,36 @@ def query_registroM410(self, cst_pis, periodo): lista_item = [] cont = 1 for resposta in query_resposta: + resp_ncm = self.env['l10n_br_fiscal.tax.pis.cofins'].search([ + ('ncm_id', '=', resposta[0]) + ]) registro_M410 = registros.RegistroM410() - registro_M410.NAT_REC = resposta[0] + if resp_ncm: + registro_M410.NAT_REC = resp_ncm.code registro_M410.VL_REC = self.transforma_valor(resposta[1]) - registro_M410.COD_CTA = '1.1.06.11.00.00' + # TODO rever esta conta + registro_M410.COD_CTA = resposta[2] lista.append(registro_M410) return lista def query_registroM600(self, periodo): query = """ select - sum(det.valor_liquido), - det.cofins_aliquota, - sum(det.cofins_valor) + sum(det.cofins_base), + det.cofins_percent, + sum(det.cofins_value) from - invoice_eletronic as ie + l10n_br_fiscal_document as ie inner join - invoice_eletronic_item as det - on ie.id = det.invoice_eletronic_id + l10n_br_fiscal_document_line as det + on ie.id = det.document_id where %s - and (ie.model in ('55','01')) - and ie.state = 'done' - and (det.cofins_cst in ('01','02','03')) - group by det.cofins_aliquota + and (ie.document_type in ('55','01')) + and (ie.state_edoc = 'autorizada') + and det.cofins_value > 0 + and (det.cofins_cst_code in ('01','02','03')) + group by det.cofins_percent """ % (periodo) self._cr.execute(query) query_resposta = self._cr.fetchall() @@ -1056,7 +1055,7 @@ def query_registroM600(self, periodo): regM605 = RegistroM605() regM605.NUM_CAMPO = '12' - regM605.COD_REC = '217201' + regM605.COD_REC = self.cod_receita_cofins regM605.VL_DEBITO = self.transforma_valor(resposta[2]) lista.append(regM605) @@ -1082,19 +1081,23 @@ def query_registroM600(self, periodo): def query_registroM800(self, periodo): query = """ select - det.cofins_cst, - sum(det.valor_liquido) + det.cofins_cst_code, + sum(det.cofins_base), + aa.code AS cod_cta from - invoice_eletronic as ie + l10n_br_fiscal_document as ie inner join - invoice_eletronic_item as det - on ie.id = det.invoice_eletronic_id + l10n_br_fiscal_document_line as det + on ie.id = det.document_id + inner join + account.account AS aa + on aa.id det.account_id where %s - and (ie.model in ('55','01')) - and ie.state = 'done' - and (det.cofins_cst in ('04','06','07','08','09')) - group by det.cofins_cst + and (ie.document_type in ('55','01')) + and (ie.state_edoc = 'autorizada') + and (det.cofins_cst_code in ('04','06','07','08','09')) + group by det.cofins_cst_code, aa.code """ % (periodo) self._cr.execute(query) query_resposta = self._cr.fetchall() @@ -1105,38 +1108,30 @@ def query_registroM800(self, periodo): registro_M800 = registros.RegistroM800() registro_M800.CST_COFINS = resposta[0] registro_M800.VL_TOT_REC = self.transforma_valor(resposta[1]) - registro_M800.COD_CTA = '1.1.06.11.00.00' + registro_M800.COD_CTA = resposta[2] lista.append(registro_M800) return lista def query_registroM810(self, cofins_cst, periodo): query = """ - select - substr(pr.name,1,3), - sum(det.valor_liquido) + select distinct + det.ncm_id, + sum(det.valor_liquido), + aa.code AS cod_cta from - invoice_eletronic as ie - inner join - invoice_eletronic_item as det - on ie.id = det.invoice_eletronic_id - inner join - product_product as pp - on pp.id = det.product_id - inner join - product_template as pt - on pt.id = pp.product_tmpl_id + l10n_br_fiscal_document as ie inner join - product_category as pc - on pc.id = pt.categ_id + l10n_br_fiscal_document_line as det + on ie.id = det.document_id inner join - product_category as pr - on pr.id = pc.parent_id + account.account AS aa + on aa.id det.account_id where %s - and (ie.model in ('55','01')) - and ie.state = 'done' - and (det.cofins_cst = \'%s\') - group by substr(pr.name,1,3) + and (ie.document_type in ('55','01')) + and (ie.state_edoc = 'autorizada') + and (det.cofins_cst_code = \'%s\') + group by det.ncm_id """ % (periodo, cofins_cst) self._cr.execute(query) query_resposta = self._cr.fetchall() @@ -1145,9 +1140,13 @@ def query_registroM810(self, cofins_cst, periodo): cont = 1 for resposta in query_resposta: registro_M810 = registros.RegistroM810() - cod_nat = resposta[0] - registro_M810.NAT_REC = cod_nat[:3] + resp_ncm = self.env['l10n_br_fiscal.tax.pis.cofins'].search([ + ('ncm_id', '=', resposta[0]) + ]) + if resp_ncm: + registro_M810.NAT_REC = resp_ncm.code registro_M810.VL_REC = self.transforma_valor(resposta[1]) - registro_M810.COD_CTA = '1.1.06.11.00.00' + # TODO rever esta conta + registro_M810.COD_CTA = resposta[2] lista.append(registro_M810) return lista diff --git a/l10n_br_sped_efd_contribuicoes/views/sped_contribuicoes_view.xml b/l10n_br_sped_efd_contribuicoes/views/sped_contribuicoes_view.xml index e7e0f1d5..19c662ab 100644 --- a/l10n_br_sped_efd_contribuicoes/views/sped_contribuicoes_view.xml +++ b/l10n_br_sped_efd_contribuicoes/views/sped_contribuicoes_view.xml @@ -4,46 +4,57 @@ SPED Contribuicoes sped.efd.contribuicoes -
- - - - - - - - - - - - - - - - - - - - - - - - -
-
- + +
+ + + + diff --git a/l10n_br_bank_api_inter/views/account_journal.xml b/l10n_br_bank_api_inter/views/account_journal.xml new file mode 100644 index 00000000..e454b87a --- /dev/null +++ b/l10n_br_bank_api_inter/views/account_journal.xml @@ -0,0 +1,35 @@ + + + + + + + account.journal.bank.form (in l10n_br_bank_api_inter) + account.journal + + + + + + + + + + + + + account.journal.form (in l10n_br_account_payment_order) + account.journal + + + + + + + + + + + + diff --git a/l10n_br_bank_api_inter/views/account_move_line.xml b/l10n_br_bank_api_inter/views/account_move_line.xml new file mode 100644 index 00000000..1923466a --- /dev/null +++ b/l10n_br_bank_api_inter/views/account_move_line.xml @@ -0,0 +1,48 @@ + + + + + + + account.move.line.form (in l10n_br_bank_api_inter) + account.move.line + + + + - - - - - diff --git a/l10n_br_bank_api_inter/views/account_journal.xml b/l10n_br_bank_api_inter/views/account_journal.xml index e454b87a..8bb99356 100644 --- a/l10n_br_bank_api_inter/views/account_journal.xml +++ b/l10n_br_bank_api_inter/views/account_journal.xml @@ -7,14 +7,14 @@ account.journal.bank.form (in l10n_br_bank_api_inter) account.journal - + - + - + @@ -23,7 +23,7 @@ account.journal - + diff --git a/l10n_br_bank_api_inter/views/account_move_line.xml b/l10n_br_bank_api_inter/views/account_move_line.xml index 1923466a..474cfa35 100644 --- a/l10n_br_bank_api_inter/views/account_move_line.xml +++ b/l10n_br_bank_api_inter/views/account_move_line.xml @@ -37,8 +37,9 @@ + From 47a639b6264ab5610e62ade30a8fc92a81669126 Mon Sep 17 00:00:00 2001 From: mcschiara Date: Thu, 11 May 2023 14:34:12 -0300 Subject: [PATCH 018/609] adicionado view_account_move --- l10n_br_bank_api_inter/__manifest__.py | 1 + .../models/account_move_line.py | 1 - .../views/account_move_view.xml | 21 +++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 l10n_br_bank_api_inter/views/account_move_view.xml diff --git a/l10n_br_bank_api_inter/__manifest__.py b/l10n_br_bank_api_inter/__manifest__.py index b403aa1a..0532de5d 100644 --- a/l10n_br_bank_api_inter/__manifest__.py +++ b/l10n_br_bank_api_inter/__manifest__.py @@ -18,6 +18,7 @@ 'data': [ 'views/account_move_line.xml', 'views/account_journal.xml', + 'views/account_move_view.xml', 'data/cron.xml', ], 'demo': [ diff --git a/l10n_br_bank_api_inter/models/account_move_line.py b/l10n_br_bank_api_inter/models/account_move_line.py index 0d9d5608..7b3f6abd 100644 --- a/l10n_br_bank_api_inter/models/account_move_line.py +++ b/l10n_br_bank_api_inter/models/account_move_line.py @@ -71,7 +71,6 @@ def generate_pdf_boleto(self): """ if self.own_number and self.pdf_boleto_id: return - import pudb;pu.db order_id = self.payment_line_ids[0].order_id with ArquivoCertificado(order_id.journal_id, 'w') as (key, cert): partner_bank_id = self.journal_id.bank_account_id diff --git a/l10n_br_bank_api_inter/views/account_move_view.xml b/l10n_br_bank_api_inter/views/account_move_view.xml new file mode 100644 index 00000000..81bf5cad --- /dev/null +++ b/l10n_br_bank_api_inter/views/account_move_view.xml @@ -0,0 +1,21 @@ + + + + + l10n_br_account.payment.inter.form + account.move + + + + + + + From e1e5b7091260cb71d5118fe0bb8d53a0cf5ea715 Mon Sep 17 00:00:00 2001 From: Mauricio-ATS Date: Thu, 11 May 2023 15:54:13 -0300 Subject: [PATCH 019/609] Codigo reduzido no plano de contas, produtos, parceiros --- account_reduced_code/__init__.py | 6 +++ account_reduced_code/__manifest__.py | 45 +++++++++++++++++++++ account_reduced_code/models/__init__.py | 21 ++++++++++ account_reduced_code/models/account.py | 12 ++++++ account_reduced_code/models/product.py | 10 +++++ account_reduced_code/models/res_partner.py | 11 +++++ account_reduced_code/views/account.xml | 15 +++++++ account_reduced_code/views/partner_view.xml | 15 +++++++ account_reduced_code/views/product_view.xml | 15 +++++++ 9 files changed, 150 insertions(+) create mode 100644 account_reduced_code/__init__.py create mode 100644 account_reduced_code/__manifest__.py create mode 100644 account_reduced_code/models/__init__.py create mode 100644 account_reduced_code/models/account.py create mode 100644 account_reduced_code/models/product.py create mode 100644 account_reduced_code/models/res_partner.py create mode 100644 account_reduced_code/views/account.xml create mode 100644 account_reduced_code/views/partner_view.xml create mode 100644 account_reduced_code/views/product_view.xml diff --git a/account_reduced_code/__init__.py b/account_reduced_code/__init__.py new file mode 100644 index 00000000..ad6c8186 --- /dev/null +++ b/account_reduced_code/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +############################################################################## +# For copyright and license notices, see __openerp__.py file in root directory +############################################################################## + +from . import models diff --git a/account_reduced_code/__manifest__.py b/account_reduced_code/__manifest__.py new file mode 100644 index 00000000..0831b261 --- /dev/null +++ b/account_reduced_code/__manifest__.py @@ -0,0 +1,45 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# 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 . +# +############################################################################## + +{ + 'name': 'Code Reduced - Código Reduzido', + 'description': """ + Cód. Reduzido no plano de contas, res_partner e produto + para ficar com o mesmo código da Contabilidade + """, + 'version': '1.0', + 'category': 'Localisation', + 'author': 'ATS Solucoes', + 'website': 'http://www.atsti.com.br', + 'license': 'AGPL-3', + 'contributors': [ + 'Carlos Silveira', + ], + 'depends': [ + 'l10n_br_base', + 'l10n_br_account', + 'product', + ], + 'data': [ + 'views/partner_view.xml', + 'views/product_view.xml', + 'views/account.xml', + ], + 'demo': [], + 'installable': True, +} diff --git a/account_reduced_code/models/__init__.py b/account_reduced_code/models/__init__.py new file mode 100644 index 00000000..0eaa806c --- /dev/null +++ b/account_reduced_code/models/__init__.py @@ -0,0 +1,21 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# 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 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 . import res_partner +from . import product +from . import account diff --git a/account_reduced_code/models/account.py b/account_reduced_code/models/account.py new file mode 100644 index 00000000..ec1b3fc4 --- /dev/null +++ b/account_reduced_code/models/account.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError +from odoo.addons import decimal_precision as dp + + +class AccountAccount(models.Model): + _inherit = 'account.account' + + code_reduced = fields.Char(size=64, string="Cód. Reduzido") diff --git a/account_reduced_code/models/product.py b/account_reduced_code/models/product.py new file mode 100644 index 00000000..a4051b24 --- /dev/null +++ b/account_reduced_code/models/product.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class ProductTemplate(models.Model): + _inherit = 'product.template' + + code_reduced = fields.Char(size=64, string="Cód. Reduzido") diff --git a/account_reduced_code/models/res_partner.py b/account_reduced_code/models/res_partner.py new file mode 100644 index 00000000..08510970 --- /dev/null +++ b/account_reduced_code/models/res_partner.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# © 2018 Carlos R. Silveira +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models, _ + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + code_reduced = fields.Char(size=64, string="Cód. Reduzido") diff --git a/account_reduced_code/views/account.xml b/account_reduced_code/views/account.xml new file mode 100644 index 00000000..1d3bf51a --- /dev/null +++ b/account_reduced_code/views/account.xml @@ -0,0 +1,15 @@ + + + + + br_account.account.form + account.account + + + + + + + + + diff --git a/account_reduced_code/views/partner_view.xml b/account_reduced_code/views/partner_view.xml new file mode 100644 index 00000000..3d61b466 --- /dev/null +++ b/account_reduced_code/views/partner_view.xml @@ -0,0 +1,15 @@ + + + + + + reduce_partner_form + res.partner + + + + + + + + diff --git a/account_reduced_code/views/product_view.xml b/account_reduced_code/views/product_view.xml new file mode 100644 index 00000000..60ffcd13 --- /dev/null +++ b/account_reduced_code/views/product_view.xml @@ -0,0 +1,15 @@ + + + + + reduced.product.form + product.template + + + + + + + + + From a00eb2f29a59439a19a7782dce358eaeef724fb0 Mon Sep 17 00:00:00 2001 From: Mauricio-ATS Date: Thu, 11 May 2023 16:31:24 -0300 Subject: [PATCH 020/609] Cod reduzido no plano de contas --- account_reduced_code/views/account.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/account_reduced_code/views/account.xml b/account_reduced_code/views/account.xml index 1d3bf51a..83b29d22 100644 --- a/account_reduced_code/views/account.xml +++ b/account_reduced_code/views/account.xml @@ -6,7 +6,7 @@ account.account - + From f06204d533caff3c1d1d3532ffddd24c9ef7a283 Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Thu, 11 May 2023 17:45:02 -0300 Subject: [PATCH 021/609] adicionado a chamada pra enviar o boleto. --- l10n_br_bank_api_inter/models/account_move_line.py | 12 ++++++++---- .../models/account_payment_order.py | 11 +++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/l10n_br_bank_api_inter/models/account_move_line.py b/l10n_br_bank_api_inter/models/account_move_line.py index 0d9d5608..2b1c004d 100644 --- a/l10n_br_bank_api_inter/models/account_move_line.py +++ b/l10n_br_bank_api_inter/models/account_move_line.py @@ -73,16 +73,20 @@ def generate_pdf_boleto(self): return import pudb;pu.db order_id = self.payment_line_ids[0].order_id + + # criar o boleto aqui + order_id.generate_payment_file() + with ArquivoCertificado(order_id.journal_id, 'w') as (key, cert): partner_bank_id = self.journal_id.bank_account_id - self.api = ApiInter( + api_inter = ApiInter( cert=(cert, key), conta_corrente=( order_id.company_partner_bank_id.acc_number + order_id.company_partner_bank_id.acc_number_dig ) ) - datas = self.api.boleto_pdf(self.own_number) + datas = api_inter.boleto_pdf(self.own_number) self.pdf_boleto_id = self.env['ir.attachment'].create( { 'name': ( @@ -142,14 +146,14 @@ def search_bank_slip(self): parser = InterFileParser(self.journal_payment_mode_id) for order in self.payment_line_ids: with ArquivoCertificado(order.order_id.journal_id, 'w') as (key, cert): - self.api = ApiInter( + api_inter = ApiInter( cert=(cert, key), conta_corrente=( order.order_id.company_partner_bank_id.acc_number + order.order_id.company_partner_bank_id.acc_number_dig ) ) - resposta = self.api.boleto_consulta(nosso_numero=self.own_number) + resposta = api_inter.boleto_consulta(nosso_numero=self.own_number) parser.parse(resposta) diff --git a/l10n_br_bank_api_inter/models/account_payment_order.py b/l10n_br_bank_api_inter/models/account_payment_order.py index e357c1e2..19543c25 100644 --- a/l10n_br_bank_api_inter/models/account_payment_order.py +++ b/l10n_br_bank_api_inter/models/account_payment_order.py @@ -82,14 +82,18 @@ def _generate_bank_inter_boleto_data(self): def _generate_bank_inter_boleto(self): with ArquivoCertificado(self.journal_id, 'w') as (key, cert): - self.api = ApiInter( + api_inter = ApiInter( cert=(cert, key), conta_corrente=(self.company_partner_bank_id.acc_number + self.company_partner_bank_id.acc_number_dig) ) data = self._generate_bank_inter_boleto_data() + + import pudb;pu.db + # PAREI AQUI O DATA esta vindo vazio + for item in data: - resposta = self.api.boleto_inclui(item._emissao_data()) + resposta = api_inter.boleto_inclui(item._emissao_data()) payment_line_id = self.payment_line_ids.filtered( lambda line: line.bank_line_id.name == item._identifier) if payment_line_id: @@ -110,8 +114,7 @@ def _gererate_bank_inter_api(self): def generate_payment_file(self): self.ensure_one() try: - if (self.company_partner_bank_id.bank_id == - self.env.ref('l10n_br_base.res_bank_077') and + if (self.company_partner_bank_id.bank_id.code_bc == '077' and self.payment_method_id.code == 'electronic'): return self._gererate_bank_inter_api() else: From c67d03e6b2ca7eafc50a90384529dd12c312bd06 Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Fri, 12 May 2023 14:31:58 -0300 Subject: [PATCH 022/609] adicionando bank_line --- .../models/account_payment_order.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/l10n_br_bank_api_inter/models/account_payment_order.py b/l10n_br_bank_api_inter/models/account_payment_order.py index 19543c25..d3bf6904 100644 --- a/l10n_br_bank_api_inter/models/account_payment_order.py +++ b/l10n_br_bank_api_inter/models/account_payment_order.py @@ -89,9 +89,6 @@ def _generate_bank_inter_boleto(self): ) data = self._generate_bank_inter_boleto_data() - import pudb;pu.db - # PAREI AQUI O DATA esta vindo vazio - for item in data: resposta = api_inter.boleto_inclui(item._emissao_data()) payment_line_id = self.payment_line_ids.filtered( @@ -114,8 +111,18 @@ def _gererate_bank_inter_api(self): def generate_payment_file(self): self.ensure_one() try: + # import pudb;pu.db if (self.company_partner_bank_id.bank_id.code_bc == '077' and - self.payment_method_id.code == 'electronic'): + self.payment_method_id.code == '240'): + #cria o bank.payment.line + bank = self.env['bank.payment.line'] + bank_line = bank.create({ + 'name': self.name, + 'order_id': self.id, + 'communication': self.name + }) + bank_values = bank_line.prepare_bank_payment_line(self.company_partner_bank_id.bank_id) + bank_line.write({bank_values}) return self._gererate_bank_inter_api() else: return super().generate_payment_file() From 125f422dfcaa8ff89119bc9a3111bb8c2ba3539d Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Fri, 12 May 2023 14:42:25 -0300 Subject: [PATCH 023/609] adicionado date --- l10n_br_bank_api_inter/models/account_payment_order.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/l10n_br_bank_api_inter/models/account_payment_order.py b/l10n_br_bank_api_inter/models/account_payment_order.py index d3bf6904..80203abc 100644 --- a/l10n_br_bank_api_inter/models/account_payment_order.py +++ b/l10n_br_bank_api_inter/models/account_payment_order.py @@ -4,7 +4,7 @@ import logging from .arquivo_certificado import ArquivoCertificado -from odoo import api, models, _ +from odoo import api, models, _, fields from odoo.exceptions import UserError _logger = logging.getLogger(__name__) @@ -119,7 +119,8 @@ def generate_payment_file(self): bank_line = bank.create({ 'name': self.name, 'order_id': self.id, - 'communication': self.name + 'communication': self.name, + 'date': fields.Date.today(), }) bank_values = bank_line.prepare_bank_payment_line(self.company_partner_bank_id.bank_id) bank_line.write({bank_values}) From 4e3b9f58acaacebeb70c990b0fdd4a248a18aa1e Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Fri, 12 May 2023 16:28:20 -0300 Subject: [PATCH 024/609] date esta vazio --- l10n_br_bank_api_inter/models/account_payment_order.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/l10n_br_bank_api_inter/models/account_payment_order.py b/l10n_br_bank_api_inter/models/account_payment_order.py index 80203abc..808178ad 100644 --- a/l10n_br_bank_api_inter/models/account_payment_order.py +++ b/l10n_br_bank_api_inter/models/account_payment_order.py @@ -114,6 +114,10 @@ def generate_payment_file(self): # import pudb;pu.db if (self.company_partner_bank_id.bank_id.code_bc == '077' and self.payment_method_id.code == '240'): + # date esta sem valor + for pay in self.payment_line_ids: + if not pay.date: + pay.write({'date': fields.Date.today()}) #cria o bank.payment.line bank = self.env['bank.payment.line'] bank_line = bank.create({ From 8c03b4135c7fa94f5e50c34063a49a6a908e0ecf Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Mon, 15 May 2023 11:31:43 -0300 Subject: [PATCH 025/609] Testes. --- l10n_br_bank_api_inter/models/account_move.py | 15 ++++++++++ .../models/account_payment_order.py | 30 +++++++++++-------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/l10n_br_bank_api_inter/models/account_move.py b/l10n_br_bank_api_inter/models/account_move.py index 78e0f32b..8c720013 100644 --- a/l10n_br_bank_api_inter/models/account_move.py +++ b/l10n_br_bank_api_inter/models/account_move.py @@ -88,3 +88,18 @@ def action_invoice_cancel(self): ) except Exception as error: raise UserError(_(error)) + + # def create_account_payment_line(self): + # res = super().create_account_payment_line() + # import pudb;pu.db + # if (self.partner_bank_id.bank_id.code_bc == '077' and + # self.payment_mode_id.payment_method_id.code == '240'): + # self.payment_order_id.draft2open() + # return res + + # def action_post(self): + # result = super().action_post() + # import pudb;pu.db + # self.load_cnab_info() + # self.payment_order_id.draft2open() + # return result \ No newline at end of file diff --git a/l10n_br_bank_api_inter/models/account_payment_order.py b/l10n_br_bank_api_inter/models/account_payment_order.py index 808178ad..2e59983e 100644 --- a/l10n_br_bank_api_inter/models/account_payment_order.py +++ b/l10n_br_bank_api_inter/models/account_payment_order.py @@ -114,20 +114,24 @@ def generate_payment_file(self): # import pudb;pu.db if (self.company_partner_bank_id.bank_id.code_bc == '077' and self.payment_method_id.code == '240'): - # date esta sem valor - for pay in self.payment_line_ids: - if not pay.date: - pay.write({'date': fields.Date.today()}) #cria o bank.payment.line - bank = self.env['bank.payment.line'] - bank_line = bank.create({ - 'name': self.name, - 'order_id': self.id, - 'communication': self.name, - 'date': fields.Date.today(), - }) - bank_values = bank_line.prepare_bank_payment_line(self.company_partner_bank_id.bank_id) - bank_line.write({bank_values}) + # bank = self.env['bank.payment.line'] + # bank_line = bank.create({ + # 'name': self.name, + # 'order_id': self.id, + # 'communication': self.name, + # }) + # date esta sem valor + # for pay in self.payment_line_ids: + # line_id = pay.move_line_id.id + # vals = [] + # vals['bank_line_id'] = bank_line.id + # if not pay.date: + # vals['date'] = fields.Date.today() + # pay.write(vals) + # bank_values = bank_line.prepare_bank_payment_line(self.company_partner_bank_id.bank_id) + # bank_line.write({bank_values}) + # self.draft2open() return self._gererate_bank_inter_api() else: return super().generate_payment_file() From 64da8a179b59021ac47fc4ec360a3f75146d905b Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Mon, 15 May 2023 14:23:17 -0300 Subject: [PATCH 026/609] =?UTF-8?q?Corre=C3=A7=C3=A3o=20do=20objeto.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- l10n_br_bank_api_inter/models/account_move.py | 4 ++-- l10n_br_bank_api_inter/models/account_payment_order.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/l10n_br_bank_api_inter/models/account_move.py b/l10n_br_bank_api_inter/models/account_move.py index 8c720013..c7019e13 100644 --- a/l10n_br_bank_api_inter/models/account_move.py +++ b/l10n_br_bank_api_inter/models/account_move.py @@ -99,7 +99,7 @@ def action_invoice_cancel(self): # def action_post(self): # result = super().action_post() - # import pudb;pu.db - # self.load_cnab_info() + # # import pudb;pu.db + # # self.load_cnab_info() # self.payment_order_id.draft2open() # return result \ No newline at end of file diff --git a/l10n_br_bank_api_inter/models/account_payment_order.py b/l10n_br_bank_api_inter/models/account_payment_order.py index 2e59983e..eaa8b9e4 100644 --- a/l10n_br_bank_api_inter/models/account_payment_order.py +++ b/l10n_br_bank_api_inter/models/account_payment_order.py @@ -42,7 +42,7 @@ def _generate_bank_inter_boleto_data(self): bankName=self.company_partner_bank_id.bank_id.name, ), ) - for line in self.bank_line_ids: + for line in self.payment_line_ids: payer = User( name=line.partner_id.legal_name, identifier=misc.punctuation_rm( @@ -68,7 +68,7 @@ def _generate_bank_inter_boleto_data(self): amount=line.amount_currency, payer=payer, issue_date=line.create_date, - due_date=line.date, + due_date=line.move_line_id.date_maturity, identifier=line.name, instructions=[ 'TESTE 1', From 3a4bf8b00c5f027ff0364bb0a2f53bfce066ab06 Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Mon, 15 May 2023 19:42:55 -0300 Subject: [PATCH 027/609] =?UTF-8?q?ajustando=20c=C3=B3digo.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/account_journal.py | 3 + l10n_br_bank_api_inter/models/account_move.py | 26 ++- .../models/account_move_line.py | 165 ++++++++++++++- .../models/account_payment_order.py | 198 +++++++++++------- .../views/account_journal.xml | 6 +- 5 files changed, 307 insertions(+), 91 deletions(-) diff --git a/l10n_br_bank_api_inter/models/account_journal.py b/l10n_br_bank_api_inter/models/account_journal.py index bf80902a..e3cb433f 100644 --- a/l10n_br_bank_api_inter/models/account_journal.py +++ b/l10n_br_bank_api_inter/models/account_journal.py @@ -11,3 +11,6 @@ class AccountJournal(models.Model): bank_inter_cert = fields.Binary(string='Bank Inter Certificate') bank_inter_key = fields.Binary(string='Bank Inter Key') + + bank_inter_id = fields.Char('Id Inter') + bank_inter_secret = fields.Char('Secret Inter') \ No newline at end of file diff --git a/l10n_br_bank_api_inter/models/account_move.py b/l10n_br_bank_api_inter/models/account_move.py index c7019e13..7550b18e 100644 --- a/l10n_br_bank_api_inter/models/account_move.py +++ b/l10n_br_bank_api_inter/models/account_move.py @@ -58,6 +58,16 @@ def gera_boleto_pdf(self): """ try: if not self.file_boleto_pdf_id: + receivable_ids = self.mapped("financial_move_line_ids") + boletos = receivable_ids.send_payment() + if not boletos: + raise UserError( + _( + "It is not possible generated boletos\n" + "Make sure the Invoice are in Confirm state and " + "Payment Mode method are CNAB." + ) + ) self._merge_pdf_boletos() boleto_id = self.file_boleto_pdf_id @@ -97,9 +107,13 @@ def action_invoice_cancel(self): # self.payment_order_id.draft2open() # return res - # def action_post(self): - # result = super().action_post() - # # import pudb;pu.db - # # self.load_cnab_info() - # self.payment_order_id.draft2open() - # return result \ No newline at end of file + def action_post(self): + result = super().action_post() + if (self.partner_bank_id.bank_id.code_bc == '077' and + self.payment_mode_id.payment_method_id.code == '240'): + self.gera_boleto_pdf() + + # import pudb;pu.db + # self.load_cnab_info() + # self.payment_order_id.draft2open() + return result \ No newline at end of file diff --git a/l10n_br_bank_api_inter/models/account_move_line.py b/l10n_br_bank_api_inter/models/account_move_line.py index 564cac63..55173b6d 100644 --- a/l10n_br_bank_api_inter/models/account_move_line.py +++ b/l10n_br_bank_api_inter/models/account_move_line.py @@ -65,6 +65,159 @@ class AccountMoveLine(models.Model): readonly=True, ) + def send_payment(self): + # super(AccountMoveLine, self).send_payment() + wrapped_boleto_list = [] + for move_line in self: + bank_account_id = move_line.payment_mode_id.fixed_journal_id.bank_account_id + bank_name_brcobranca = get_brcobranca_bank( + bank_account_id, move_line.payment_mode_id.payment_method_code + ) + precision = self.env["decimal.precision"] + precision_account = precision.precision_get("Account") + + boleto_cnab_api_data = { + "bank": bank_name_brcobranca[0], + "valor": str("%.2f" % move_line.debit), + "cedente": move_line.company_id.partner_id.legal_name, + "cedente_endereco": (move_line.company_id.partner_id.street_name or "") + + " " + + (move_line.company_id.partner_id.street_number or "") + + ", " + + (move_line.company_id.partner_id.district or "") + + ", " + + (move_line.company_id.partner_id.city_id.name or "") + + " - " + + (move_line.company_id.partner_id.state_id.code or "") + + " " + + ("CEP:" + move_line.company_id.partner_id.zip or ""), + "documento_cedente": move_line.company_id.cnpj_cpf, + "sacado": move_line.partner_id.legal_name, + "sacado_documento": move_line.partner_id.cnpj_cpf, + "agencia": bank_account_id.bra_number, + "conta_corrente": bank_account_id.acc_number, + "convenio": move_line.payment_mode_id.code_convetion, + "carteira": str(move_line.payment_mode_id.boleto_wallet), + "nosso_numero": int( + "".join(i for i in move_line.own_number if i.isdigit()) + ), + "documento_numero": move_line.document_number, + "data_vencimento": move_line.date_maturity.strftime("%Y/%m/%d"), + "data_documento": move_line.move_id.invoice_date.strftime("%Y/%m/%d"), + "especie": move_line.payment_mode_id.boleto_species, + "moeda": DICT_BRCOBRANCA_CURRENCY["R$"], + "aceite": move_line.payment_mode_id.boleto_accept, + "sacado_endereco": (move_line.partner_id.street_name or "") + + " " + + (move_line.partner_id.street_number or "") + + ", " + + (move_line.partner_id.district or "") + + ", " + + (move_line.partner_id.city_id.name or "") + + " - " + + (move_line.partner_id.state_id.code or "") + + " " + + ("CEP:" + move_line.partner_id.zip or ""), + "data_processamento": move_line.move_id.invoice_date.strftime( + "%Y/%m/%d" + ), + "instrucao1": move_line.payment_mode_id.instructions or "", + } + + # Instrução de Juros + if move_line.payment_mode_id.boleto_interest_perc > 0.0: + valor_juros = round( + move_line.debit + * ((move_line.payment_mode_id.boleto_interest_perc / 100) / 30), + precision_account, + ) + instrucao_juros = ( + "APÓS VENCIMENTO COBRAR PERCENTUAL" + + " DE %s %% AO MÊS ( R$ %s AO DIA )" + % ( + ( + "%.2f" % move_line.payment_mode_id.boleto_interest_perc + ).replace(".", ","), + ("%.2f" % valor_juros).replace(".", ","), + ) + ) + boleto_cnab_api_data.update( + { + "instrucao3": instrucao_juros, + } + ) + + # Instrução Multa + if move_line.payment_mode_id.boleto_fee_perc > 0.0: + valor_multa = round( + move_line.debit * (move_line.payment_mode_id.boleto_fee_perc / 100), + precision_account, + ) + instrucao_multa = ( + "APÓS VENCIMENTO COBRAR MULTA" + + " DE %s %% ( R$ %s )" + % ( + ("%.2f" % move_line.payment_mode_id.boleto_fee_perc).replace( + ".", "," + ), + ("%.2f" % valor_multa).replace(".", ","), + ) + ) + boleto_cnab_api_data.update( + { + "instrucao4": instrucao_multa, + } + ) + + # Instrução Desconto + if move_line.boleto_discount_perc > 0.0: + valor_desconto = round( + move_line.debit * (move_line.boleto_discount_perc / 100), + precision_account, + ) + instrucao_desconto_vencimento = ( + "CONCEDER DESCONTO DE" + " %s %% " + "ATÉ O VENCIMENTO EM %s ( R$ %s )" + % ( + ("%.2f" % move_line.boleto_discount_perc).replace(".", ","), + move_line.date_maturity.strftime("%d/%m/%Y"), + ("%.2f" % valor_desconto).replace(".", ","), + ) + ) + boleto_cnab_api_data.update( + { + "instrucao5": instrucao_desconto_vencimento, + } + ) + + bank_account = move_line.payment_mode_id.fixed_journal_id.bank_account_id + if bank_account_id.bank_id.code_bc in ("021", "004"): + boleto_cnab_api_data.update( + { + "digito_conta_corrente": bank_account.acc_number_dig, + } + ) + + # Fields used in Sicredi and Sicoob Banks + if bank_account_id.bank_id.code_bc in ("748", "756"): + boleto_cnab_api_data.update( + { + "byte_idt": move_line.payment_mode_id.boleto_byte_idt, + "posto": move_line.payment_mode_id.boleto_post, + } + ) + # Campo usado no Unicred + if bank_account_id.bank_id.code_bc == "136": + boleto_cnab_api_data.update( + { + "conta_corrente_dv": bank_account.acc_number_dig, + } + ) + + wrapped_boleto_list.append(boleto_cnab_api_data) + + return wrapped_boleto_list + def generate_pdf_boleto(self): """ Creates a new attachment with the Boleto PDF @@ -83,7 +236,9 @@ def generate_pdf_boleto(self): conta_corrente=( order_id.company_partner_bank_id.acc_number + order_id.company_partner_bank_id.acc_number_dig - ) + ), + clientId=self.journal_id.bank_inter_id, + clientSecret=self.journal_id.bank_inter_secret ) datas = api_inter.boleto_pdf(self.own_number) self.pdf_boleto_id = self.env['ir.attachment'].create( @@ -133,7 +288,9 @@ def drop_bank_slip(self): conta_corrente=( order_id.company_partner_bank_id.acc_number + order_id.company_partner_bank_id.acc_number_dig - ) + ), + clientId=order_id.journal_id.bank_inter_id, + clientSecret=order_id.journal_id.bank_inter_secret ) self.api.boleto_baixa(self.own_number, codigo_baixa) self.bank_inter_state = "baixado" @@ -150,7 +307,9 @@ def search_bank_slip(self): conta_corrente=( order.order_id.company_partner_bank_id.acc_number + order.order_id.company_partner_bank_id.acc_number_dig - ) + ), + clientId=order.order_id.journal_id.bank_inter_id, + clientSecret=order.order_id.journal_id.bank_inter_secret ) resposta = api_inter.boleto_consulta(nosso_numero=self.own_number) diff --git a/l10n_br_bank_api_inter/models/account_payment_order.py b/l10n_br_bank_api_inter/models/account_payment_order.py index eaa8b9e4..e9956c15 100644 --- a/l10n_br_bank_api_inter/models/account_payment_order.py +++ b/l10n_br_bank_api_inter/models/account_payment_order.py @@ -1,6 +1,8 @@ # Copyright 2020 KMEE # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import re +from datetime import timedelta import logging from .arquivo_certificado import ArquivoCertificado @@ -15,11 +17,6 @@ except ImportError: _logger.error("Biblioteca erpbrasil.bank.inter não instalada") -try: - from febraban.cnab240.user import User, UserAddress, UserBank -except ImportError: - _logger.error("Biblioteca febraban não instalada") - try: from erpbrasil.base import misc except ImportError: @@ -30,75 +27,135 @@ class AccountPaymentOrder(models.Model): _inherit = 'account.payment.order' def _generate_bank_inter_boleto_data(self): + import pudb;pu.db dados = [] - myself = User( - name=self.company_id.legal_name, - identifier=misc.punctuation_rm(self.company_id.cnpj_cpf), - bank=UserBank( - bankId=self.company_partner_bank_id.bank_id.code_bc, - branchCode=self.company_partner_bank_id.bra_number, - accountNumber=self.company_partner_bank_id.acc_number, - accountVerifier=self.company_partner_bank_id.acc_number_dig, - bankName=self.company_partner_bank_id.bank_id.name, - ), - ) + instrucao = self.payment_mode_id.instructions or '' + instrucao1 = '' + if instrucao and len(instrucao) > 80: + instrucao = instrucao[:80] + instrucao1 = instrucao[80:] + + precision = self.env["decimal.precision"] + precision_account = precision.precision_get("Account") for line in self.payment_line_ids: - payer = User( - name=line.partner_id.legal_name, - identifier=misc.punctuation_rm( - line.partner_id.cnpj_cpf - ), - email=line.partner_id.email or '', - personType=( - "FISICA" if line.partner_id.company_type == 'person' - else 'JURIDICA'), - phone=misc.punctuation_rm( - line.partner_id.phone).replace(" ", ""), - address=UserAddress( - streetLine1=line.partner_id.street or '', - district=line.partner_id.district or '', - city=line.partner_id.city_id.name or '', - stateCode=line.partner_id.state_id.code or '', - zipCode=misc.punctuation_rm(line.partner_id.zip), - streetNumber=line.partner_id.street_number, + move_line = line.move_line_id + # Instrução de Juros + tipo_mora = "ISENTO" + data_mora = '' + valor_juro = 0 + taxa_mora = 0 + if self.payment_mode_id.boleto_interest_perc > 0.0: + tipo_mora = "TAXAMENSAL" + data_mora = (move_line.date_maturity + timedelta(days=1)).isoformat() + taxa_mora = move_line.payment_mode_id.boleto_interest_perc + valor_juro = round( + move_line.debit + * ((move_line.payment_mode_id.boleto_interest_perc / 100) / 30), + precision_account, + ) + # Instrução Multa + tipo_multa = "NAOTEMMULTA" + data_multa = '' + taxa_multa = 0 + valor_multa = 0 + if move_line.payment_mode_id.boleto_fee_perc > 0.0: + tipo_multa = "PERCENTUAL" # Percentual + data_multa = (move_line.date_maturity + timedelta(days=1)).isoformat() + taxa_multa = move_line.payment_mode_id.boleto_fee_perc + valor_multa = round( + move_line.debit * (move_line.payment_mode_id.boleto_fee_perc / 100), + precision_account, ) - ) - slip = BoletoInter( - sender=myself, - amount=line.amount_currency, - payer=payer, - issue_date=line.create_date, - due_date=line.move_line_id.date_maturity, - identifier=line.name, - instructions=[ - 'TESTE 1', - 'TESTE 2', - 'TESTE 3', - 'TESTE 4', - ] - ) - dados.append(slip) + # Instrução Desconto + if move_line.boleto_discount_perc > 0.0: + valor_desconto = round( + move_line.debit * (move_line.boleto_discount_perc / 100), + precision_account, + ) + email = move_line.partner_id.email or "" + email = email[:email.find(';')] + vals = { + "seuNumero": move_line.document_number, + "dataVencimento": move_line.date_maturity.isoformat(), + "valorNominal": move_line.debit, + "numDiasAgenda": 60, + "pagador":{ + "cpfCnpj": re.sub("[^0-9]", "",move_line.partner_id.cnpj_cpf), + "nome": move_line.partner_id.legal_name, + "email": email, + "telefone":"", + "ddd":"", + "cep": re.sub("[^0-9]", "", move_line.partner_id.zip), + "numero": move_line.partner_id.street_number or "", + "complemento": move_line.partner_id.street2 or "", + "bairro": move_line.partner_id.district or "", + "cidade": move_line.partner_id.city_id.name or "", + "uf": move_line.partner_id.state_id.code or "", + "endereco": move_line.partner_id.street_name or "", + "tipoPessoa": "JURIDICA" if move_line.partner_id.is_company else "FISICA" + }, + "mensagem": { + "linha1": instrucao, + "linha2": instrucao1, + "linha3": "", + "linha4": "", + "linha5": "", + }, + "desconto1":{ + "codigoDesconto": "NAOTEMDESCONTO", + "taxa": 0, + "valor": 0, + "data": "" + }, + "desconto2": { + "codigoDesconto": "NAOTEMDESCONTO", + "taxa": 0, + "valor": 0, + "data": "" + }, + "desconto3":{ + "codigoDesconto": "NAOTEMDESCONTO", + "taxa": 0, + "valor": 0, + "data": "" + }, + "multa": { + "codigoMulta": tipo_multa, + "data": data_multa, + "taxa": taxa_multa, + "valor": valor_multa, + }, + "mora": { + "codigoMora": tipo_mora, + "data": data_mora, + "taxa": taxa_mora, + "valor": valor_juro, + }, + } + dados.append(vals) return dados def _generate_bank_inter_boleto(self): + import pudb;pu.db with ArquivoCertificado(self.journal_id, 'w') as (key, cert): api_inter = ApiInter( cert=(cert, key), conta_corrente=(self.company_partner_bank_id.acc_number + - self.company_partner_bank_id.acc_number_dig) + self.company_partner_bank_id.acc_number_dig), + clientId=self.journal_id.bank_inter_id, + clientSecret=self.journal_id.bank_inter_secret ) data = self._generate_bank_inter_boleto_data() - for item in data: - resposta = api_inter.boleto_inclui(item._emissao_data()) - payment_line_id = self.payment_line_ids.filtered( - lambda line: line.bank_line_id.name == item._identifier) - if payment_line_id: - payment_line_id.move_line_id.own_number = \ - resposta['nossoNumero'] - # bank_line_id.seu_numero = resposta['seuNumero'] - # bank_line_id.linha_digitavel = resposta['linhaDigitavel'] - # bank_line_id.barcode = resposta['codigoBarras'] + resposta, result = api_inter.boleto_inclui(item) + if resposta.status_code == 200: + payment_line_id = self.payment_line_ids.filtered( + lambda line: line.document_number == item["nossoNumero"]) + payment_line_id.move_line_id.write({ + 'nosso_numero': result["nossoNumero"], + 'codigo_barra': result["codigoBarras"], + 'linha_digitavel': result["linhaDigitavel"] + }) return False, False def _gererate_bank_inter_api(self): @@ -111,27 +168,8 @@ def _gererate_bank_inter_api(self): def generate_payment_file(self): self.ensure_one() try: - # import pudb;pu.db if (self.company_partner_bank_id.bank_id.code_bc == '077' and self.payment_method_id.code == '240'): - #cria o bank.payment.line - # bank = self.env['bank.payment.line'] - # bank_line = bank.create({ - # 'name': self.name, - # 'order_id': self.id, - # 'communication': self.name, - # }) - # date esta sem valor - # for pay in self.payment_line_ids: - # line_id = pay.move_line_id.id - # vals = [] - # vals['bank_line_id'] = bank_line.id - # if not pay.date: - # vals['date'] = fields.Date.today() - # pay.write(vals) - # bank_values = bank_line.prepare_bank_payment_line(self.company_partner_bank_id.bank_id) - # bank_line.write({bank_values}) - # self.draft2open() return self._gererate_bank_inter_api() else: return super().generate_payment_file() diff --git a/l10n_br_bank_api_inter/views/account_journal.xml b/l10n_br_bank_api_inter/views/account_journal.xml index 8bb99356..dac2cb20 100644 --- a/l10n_br_bank_api_inter/views/account_journal.xml +++ b/l10n_br_bank_api_inter/views/account_journal.xml @@ -13,12 +13,14 @@ + + - + From b5cdb6b8ce4d26fda791c6ebcedf9392d40ef17a Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Tue, 16 May 2023 08:56:01 -0300 Subject: [PATCH 028/609] =?UTF-8?q?c=C3=B3digo=20errado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/account_move_line.py | 153 ------------------ 1 file changed, 153 deletions(-) diff --git a/l10n_br_bank_api_inter/models/account_move_line.py b/l10n_br_bank_api_inter/models/account_move_line.py index 55173b6d..1e3241a1 100644 --- a/l10n_br_bank_api_inter/models/account_move_line.py +++ b/l10n_br_bank_api_inter/models/account_move_line.py @@ -65,159 +65,6 @@ class AccountMoveLine(models.Model): readonly=True, ) - def send_payment(self): - # super(AccountMoveLine, self).send_payment() - wrapped_boleto_list = [] - for move_line in self: - bank_account_id = move_line.payment_mode_id.fixed_journal_id.bank_account_id - bank_name_brcobranca = get_brcobranca_bank( - bank_account_id, move_line.payment_mode_id.payment_method_code - ) - precision = self.env["decimal.precision"] - precision_account = precision.precision_get("Account") - - boleto_cnab_api_data = { - "bank": bank_name_brcobranca[0], - "valor": str("%.2f" % move_line.debit), - "cedente": move_line.company_id.partner_id.legal_name, - "cedente_endereco": (move_line.company_id.partner_id.street_name or "") - + " " - + (move_line.company_id.partner_id.street_number or "") - + ", " - + (move_line.company_id.partner_id.district or "") - + ", " - + (move_line.company_id.partner_id.city_id.name or "") - + " - " - + (move_line.company_id.partner_id.state_id.code or "") - + " " - + ("CEP:" + move_line.company_id.partner_id.zip or ""), - "documento_cedente": move_line.company_id.cnpj_cpf, - "sacado": move_line.partner_id.legal_name, - "sacado_documento": move_line.partner_id.cnpj_cpf, - "agencia": bank_account_id.bra_number, - "conta_corrente": bank_account_id.acc_number, - "convenio": move_line.payment_mode_id.code_convetion, - "carteira": str(move_line.payment_mode_id.boleto_wallet), - "nosso_numero": int( - "".join(i for i in move_line.own_number if i.isdigit()) - ), - "documento_numero": move_line.document_number, - "data_vencimento": move_line.date_maturity.strftime("%Y/%m/%d"), - "data_documento": move_line.move_id.invoice_date.strftime("%Y/%m/%d"), - "especie": move_line.payment_mode_id.boleto_species, - "moeda": DICT_BRCOBRANCA_CURRENCY["R$"], - "aceite": move_line.payment_mode_id.boleto_accept, - "sacado_endereco": (move_line.partner_id.street_name or "") - + " " - + (move_line.partner_id.street_number or "") - + ", " - + (move_line.partner_id.district or "") - + ", " - + (move_line.partner_id.city_id.name or "") - + " - " - + (move_line.partner_id.state_id.code or "") - + " " - + ("CEP:" + move_line.partner_id.zip or ""), - "data_processamento": move_line.move_id.invoice_date.strftime( - "%Y/%m/%d" - ), - "instrucao1": move_line.payment_mode_id.instructions or "", - } - - # Instrução de Juros - if move_line.payment_mode_id.boleto_interest_perc > 0.0: - valor_juros = round( - move_line.debit - * ((move_line.payment_mode_id.boleto_interest_perc / 100) / 30), - precision_account, - ) - instrucao_juros = ( - "APÓS VENCIMENTO COBRAR PERCENTUAL" - + " DE %s %% AO MÊS ( R$ %s AO DIA )" - % ( - ( - "%.2f" % move_line.payment_mode_id.boleto_interest_perc - ).replace(".", ","), - ("%.2f" % valor_juros).replace(".", ","), - ) - ) - boleto_cnab_api_data.update( - { - "instrucao3": instrucao_juros, - } - ) - - # Instrução Multa - if move_line.payment_mode_id.boleto_fee_perc > 0.0: - valor_multa = round( - move_line.debit * (move_line.payment_mode_id.boleto_fee_perc / 100), - precision_account, - ) - instrucao_multa = ( - "APÓS VENCIMENTO COBRAR MULTA" - + " DE %s %% ( R$ %s )" - % ( - ("%.2f" % move_line.payment_mode_id.boleto_fee_perc).replace( - ".", "," - ), - ("%.2f" % valor_multa).replace(".", ","), - ) - ) - boleto_cnab_api_data.update( - { - "instrucao4": instrucao_multa, - } - ) - - # Instrução Desconto - if move_line.boleto_discount_perc > 0.0: - valor_desconto = round( - move_line.debit * (move_line.boleto_discount_perc / 100), - precision_account, - ) - instrucao_desconto_vencimento = ( - "CONCEDER DESCONTO DE" + " %s %% " - "ATÉ O VENCIMENTO EM %s ( R$ %s )" - % ( - ("%.2f" % move_line.boleto_discount_perc).replace(".", ","), - move_line.date_maturity.strftime("%d/%m/%Y"), - ("%.2f" % valor_desconto).replace(".", ","), - ) - ) - boleto_cnab_api_data.update( - { - "instrucao5": instrucao_desconto_vencimento, - } - ) - - bank_account = move_line.payment_mode_id.fixed_journal_id.bank_account_id - if bank_account_id.bank_id.code_bc in ("021", "004"): - boleto_cnab_api_data.update( - { - "digito_conta_corrente": bank_account.acc_number_dig, - } - ) - - # Fields used in Sicredi and Sicoob Banks - if bank_account_id.bank_id.code_bc in ("748", "756"): - boleto_cnab_api_data.update( - { - "byte_idt": move_line.payment_mode_id.boleto_byte_idt, - "posto": move_line.payment_mode_id.boleto_post, - } - ) - # Campo usado no Unicred - if bank_account_id.bank_id.code_bc == "136": - boleto_cnab_api_data.update( - { - "conta_corrente_dv": bank_account.acc_number_dig, - } - ) - - wrapped_boleto_list.append(boleto_cnab_api_data) - - return wrapped_boleto_list - def generate_pdf_boleto(self): """ Creates a new attachment with the Boleto PDF From 67ade9e9dec2195933a64a25ea67312195c877b2 Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Tue, 16 May 2023 10:02:58 -0300 Subject: [PATCH 029/609] validando info. --- l10n_br_bank_api_inter/models/account_move.py | 15 +++++---------- .../models/account_payment_order.py | 3 +-- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/l10n_br_bank_api_inter/models/account_move.py b/l10n_br_bank_api_inter/models/account_move.py index 7550b18e..0742b58e 100644 --- a/l10n_br_bank_api_inter/models/account_move.py +++ b/l10n_br_bank_api_inter/models/account_move.py @@ -58,16 +58,6 @@ def gera_boleto_pdf(self): """ try: if not self.file_boleto_pdf_id: - receivable_ids = self.mapped("financial_move_line_ids") - boletos = receivable_ids.send_payment() - if not boletos: - raise UserError( - _( - "It is not possible generated boletos\n" - "Make sure the Invoice are in Confirm state and " - "Payment Mode method are CNAB." - ) - ) self._merge_pdf_boletos() boleto_id = self.file_boleto_pdf_id @@ -111,6 +101,11 @@ def action_post(self): result = super().action_post() if (self.partner_bank_id.bank_id.code_bc == '077' and self.payment_mode_id.payment_method_id.code == '240'): + if (not self.journal_id.bank_inter_id or + not self.journal_id.bank_inter_secret): + raise UserError( + _("Informe o Id é chave do banco Inter.") + ) self.gera_boleto_pdf() # import pudb;pu.db diff --git a/l10n_br_bank_api_inter/models/account_payment_order.py b/l10n_br_bank_api_inter/models/account_payment_order.py index e9956c15..f9e870c5 100644 --- a/l10n_br_bank_api_inter/models/account_payment_order.py +++ b/l10n_br_bank_api_inter/models/account_payment_order.py @@ -27,7 +27,6 @@ class AccountPaymentOrder(models.Model): _inherit = 'account.payment.order' def _generate_bank_inter_boleto_data(self): - import pudb;pu.db dados = [] instrucao = self.payment_mode_id.instructions or '' instrucao1 = '' @@ -136,7 +135,7 @@ def _generate_bank_inter_boleto_data(self): return dados def _generate_bank_inter_boleto(self): - import pudb;pu.db + # import pudb;pu.db with ArquivoCertificado(self.journal_id, 'w') as (key, cert): api_inter = ApiInter( cert=(cert, key), From 96e22604e8f71c1e6504ea5e0db933e7e769f23d Mon Sep 17 00:00:00 2001 From: Carlos Silveira Date: Tue, 16 May 2023 14:01:01 -0300 Subject: [PATCH 030/609] =?UTF-8?q?corre=C3=A7ao.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- l10n_br_bank_api_inter/models/account_move.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/l10n_br_bank_api_inter/models/account_move.py b/l10n_br_bank_api_inter/models/account_move.py index 0742b58e..e9371c0c 100644 --- a/l10n_br_bank_api_inter/models/account_move.py +++ b/l10n_br_bank_api_inter/models/account_move.py @@ -101,14 +101,10 @@ def action_post(self): result = super().action_post() if (self.partner_bank_id.bank_id.code_bc == '077' and self.payment_mode_id.payment_method_id.code == '240'): - if (not self.journal_id.bank_inter_id or - not self.journal_id.bank_inter_secret): + if (not self.partner_bank_id.journal_id.bank_inter_id or + not self.partner_bank_id.journal_id.bank_inter_secret): raise UserError( _("Informe o Id é chave do banco Inter.") ) self.gera_boleto_pdf() - - # import pudb;pu.db - # self.load_cnab_info() - # self.payment_order_id.draft2open() return result \ No newline at end of file From 5f640387fd6133cad2c5f03d3ccc47aedde8b12d Mon Sep 17 00:00:00 2001 From: mcschiara Date: Tue, 16 May 2023 14:39:13 -0300 Subject: [PATCH 031/609] =?UTF-8?q?alterado=20posi=C3=A7=C3=A3o=20dos=20ca?= =?UTF-8?q?mpos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- l10n_br_bank_api_inter/views/account_journal.xml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/l10n_br_bank_api_inter/views/account_journal.xml b/l10n_br_bank_api_inter/views/account_journal.xml index dac2cb20..455fc652 100644 --- a/l10n_br_bank_api_inter/views/account_journal.xml +++ b/l10n_br_bank_api_inter/views/account_journal.xml @@ -4,7 +4,7 @@ - + - + From e046ba94fdca295dc3a52e369b442b3ef8e351a9 Mon Sep 17 00:00:00 2001 From: Mauricio-ATS Date: Wed, 17 May 2023 17:36:29 -0300 Subject: [PATCH 032/609] Modulo para criar e editar parcelas na fatura --- payment_installment/__init__.py | 3 + payment_installment/__manifest__.py | 25 ++ payment_installment/models/__init__.py | 3 + payment_installment/models/account_move.py | 305 ++++++++++++++++++ .../security/ir.model.access.csv | 3 + .../views/payment_installment.xml | 56 ++++ 6 files changed, 395 insertions(+) create mode 100644 payment_installment/__init__.py create mode 100644 payment_installment/__manifest__.py create mode 100644 payment_installment/models/__init__.py create mode 100644 payment_installment/models/account_move.py create mode 100644 payment_installment/security/ir.model.access.csv create mode 100644 payment_installment/views/payment_installment.xml diff --git a/payment_installment/__init__.py b/payment_installment/__init__.py new file mode 100644 index 00000000..cde864ba --- /dev/null +++ b/payment_installment/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models diff --git a/payment_installment/__manifest__.py b/payment_installment/__manifest__.py new file mode 100644 index 00000000..2af690e4 --- /dev/null +++ b/payment_installment/__manifest__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + + +{ + 'name': 'Payment Installment', + 'version': '14.0.1.0.0', + 'category': 'Account', + 'description': """ + Permite criar e editar parcelas geradas para Faturas. + """, + 'author': 'ATSTi Solucoes', + 'website': 'http://www.atsti.com.br', + 'depends': [ + 'l10n_br_account', + 'account_payment_mode', + ], + 'data': [ + 'views/payment_installment.xml', + 'security/ir.model.access.csv', + ], + 'demo': [], + 'installable': True, + 'auto_install': False, +} + diff --git a/payment_installment/models/__init__.py b/payment_installment/models/__init__.py new file mode 100644 index 00000000..fa4571fd --- /dev/null +++ b/payment_installment/models/__init__.py @@ -0,0 +1,3 @@ +# -*- encoding: utf-8 -*- + +from . import account_move diff --git a/payment_installment/models/account_move.py b/payment_installment/models/account_move.py new file mode 100644 index 00000000..dba9d141 --- /dev/null +++ b/payment_installment/models/account_move.py @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- © 2017 Carlos R. Silveira, ATSti +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models, _ +from datetime import date, datetime + +class AccountMove(models.Model): + _inherit = 'account.move' + + parcela_ids = fields.One2many( + 'invoice.parcela', 'move_id', + string=u"Parcelas") + num_parcela = fields.Integer('Núm. Parcela') + dia_vcto = fields.Integer('Dia Vencimento', default=0) + rateio_frete = fields.Boolean('Rateio do Frete', default=False) + vlr_prim_prc = fields.Float('Valor Prim. Parcela', default=0.0) + payment_mode_id = fields.Many2one( + 'account.payment.mode', string=u"Modo de pagamento") + + def action_confirma_parcela(self): + import wdb + wdb.set_trace() + if self.num_parcela > 0: + parcela = 0 + for fin in self.financial_move_line_ids: + parc = self.parcela_ids[parcela] + fin.with_context(check_move_validity=False).update({ + 'date_maturity': parc.data_vencimento, + 'amount_currency': parc.valor, + 'debit': parc.valor, + 'balance': parc.valor, + 'credit': 0.0, + }) + parcela += 1 + account = fin.account_id + for prc in self.parcela_ids[parcela:]: + create_method = self.env['account.move.line'].with_context(check_move_validity=False).create + candidate = create_method({ + 'name': self.payment_reference or '', + 'debit': prc.valor, + 'balance': prc.valor, + 'credit': 0.0, + 'quantity': 1.0, + 'amount_currency': prc.valor, + 'date_maturity': prc.data_vencimento, + 'move_id': self.id, + 'currency_id': self.currency_id.id, + 'account_id': account.id, + 'partner_id': self.commercial_partner_id.id, + 'exclude_from_invoice_tab': True, + }) + + def calcular_vencimento(self, dia_preferencia, parcela): + if self.invoice_date: + hj = self.invoice_date + else: + hj = date.today() + dia = hj.day + mes = hj.month + ano = hj.year + if dia_preferencia: + if dia >= dia_preferencia: + mes = mes + 1 + if mes > 12: + mes = 1 + ano = ano + 1 + dia = dia_preferencia + mes = mes + parcela + + if mes > 12 and mes < 25: + mes = mes - 12 + ano = ano + 1 + if mes > 24 and mes < 37: + mes = mes - 24 + ano = ano + 2 + if mes > 36 and mes < 49: + mes = mes - 36 + ano = ano + 3 + if mes > 48 and mes < 61: + mes = mes - 48 + ano = ano + 4 + if mes > 60 and mes < 73: + mes = mes - 60 + ano = ano + 5 + if mes > 72 and mes < 85: + mes = mes - 72 + ano = ano + 6 + if mes > 84 and mes < 97: + mes = mes - 84 + ano = ano + 7 + if mes > 96 and mes < 109: + mes = mes - 96 + ano = ano + 8 + if mes > 108 and mes < 121: + mes = mes - 108 + ano = ano + 9 + + if dia > 28 and mes == 2: + dia = 28 + if dia == 31 and mes not in (1,3,5,7,8,10,12): + dia = 30 + data_str = '%s-%s-%s' %(ano, mes, dia) + data_vcto = datetime.strptime(data_str,'%Y-%m-%d').date() + return data_vcto + + @api.depends('num_parcela', 'dia_vcto', 'vlr_prim_prc') + def action_calcula_parcela(self): + prcs = [] + prc = 0 + if self.rateio_frete: + total = self.amount_total + else: + total = self.amount_total - self.amount_freight_value + valor_prc = 0.0 + if self.vlr_prim_prc: + total = self.currency_id.round(total - self.vlr_prim_prc) + if self.num_parcela > 1: + valor_prc = self.currency_id.round(total / (self.num_parcela - 1)) + else: + if self.num_parcela > 1: + valor_prc = self.currency_id.round(total / (self.num_parcela - 1)) + else: + valor_prc = self.currency_id.round(total) + else: + if self.num_parcela > 0: + valor_prc = self.currency_id.round(total / self.num_parcela) + else: + valor_prc = self.currency_id.round(total) + valor_parc = valor_prc + while (prc < self.num_parcela): + data_parc = self.calcular_vencimento(self.dia_vcto,prc) + if prc == 0 and self.vlr_prim_prc > 0.0: + valor_parc = self.currency_id.round(self.vlr_prim_prc) + if prc == 0 and self.vlr_prim_prc == 0.0: + total -= valor_parc + elif prc > 0: + total -= valor_parc + if (self.num_parcela - prc) == 1: + if total > 0.0 or total < 0.0: + valor_parc = self.currency_id.round(valor_parc + total) + if not self.rateio_frete and prc == 0: + valor_parc = valor_parc + self.amount_freight_value + prcs.append((0, None, { + 'currency_id': self.currency_id.id, + 'data_vencimento': data_parc, + 'valor': self.currency_id.round(valor_parc), + 'numero_fatura': str(prc+1).zfill(2), + 'payment_mode_id': self.payment_mode_id.id, + })) + valor_parc = valor_prc + prc += 1 + if prcs: + if self.parcela_ids: + self.parcela_ids.unlink() + self.parcela_ids = prcs + + + def action_move_create(self): + """ Creates invoice related analytics and financial move lines """ + account_move = self.env['account.move'] + for inv in self: + if not inv.journal_id.sequence_id: + raise UserError(_('Please define sequence on the journal related to this invoice.')) + if not inv.invoice_line_ids: + raise UserError(_('Please create some invoice lines.')) + if inv.move_id: + continue + + ctx = dict(self._context, lang=inv.partner_id.lang) + + if not inv.invoice_date: + inv.with_context(ctx).write({'invoice_date': fields.Date.context_today(self)}) + date_due = inv.invoice_date + if inv.parcela_ids: + for prc in inv.parcela_ids: + date_due= prc.data_vencimento + break + if not inv.date_due: + inv.with_context(ctx).write({'date_due': date_due}) + company_currency = inv.company_id.currency_id + + # create move lines (one per invoice line + eventual taxes and analytic lines) + iml = inv.invoice_line_move_line_get() + iml += inv.tax_line_move_line_get() + + diff_currency = inv.currency_id != company_currency + # create one move line for the total and possibly adjust the other lines amount + total, total_currency, iml = inv.with_context(ctx).compute_invoice_totals(company_currency, iml) + + name = inv.name or '/' + + if inv.parcela_ids: + for prc in inv.parcela_ids: + if total < 0: + prc.valor = prc.valor*(-1) + iml.append({ + 'type': 'dest', + 'name': name, + 'price': prc.valor, + 'account_id': inv.account_id.id, + 'payment_mode_id': prc.payment_mode_id.id, + 'date_maturity': prc.data_vencimento, + 'amount_currency': prc.valor, + 'currency_id': inv.currency_id.id, + 'move_id': inv.id + }) + prc.valor = prc.valor*(-1) + + elif inv.payment_term_id: + totlines = inv.with_context(ctx).payment_term_id.with_context(currency_id=company_currency.id).compute(total, inv.invoice_date)[0] + res_amount_currency = total_currency + ctx['date'] = inv.date or inv.invoice_date + for i, t in enumerate(totlines): + if inv.currency_id != company_currency: + amount_currency = company_currency.with_context(ctx).compute(t[1], inv.currency_id) + else: + amount_currency = False + + # last line: add the diff + res_amount_currency -= amount_currency or 0 + if i + 1 == len(totlines): + amount_currency += res_amount_currency + + iml.append({ + 'type': 'dest', + 'name': name, + 'price': t[1], + 'account_id': inv.account_id.id, + 'date_maturity': t[0], + 'payment_mode_id': inv.payment_mode_id.id, + 'amount_currency': diff_currency and amount_currency, + 'currency_id': diff_currency and inv.currency_id.id, + 'move_id': inv.id + }) + else: + iml.append({ + 'type': 'dest', + 'name': name, + 'price': total, + 'account_id': inv.account_id.id, + 'date_maturity': inv.date_due, + 'amount_currency': diff_currency and total_currency, + 'currency_id': diff_currency and inv.currency_id.id, + 'move_id': inv.id + }) + part = self.env['res.partner']._find_accounting_partner(inv.partner_id) + line = [(0, 0, self.line_get_convert(l, part.id)) for l in iml] + line = inv.group_lines(iml, line) + + journal = inv.journal_id.with_context(ctx) + line = inv.finalize_invoice_move_lines(line) + + date = inv.date or inv.invoice_date + move_vals = { + 'ref': inv.reference, + 'line_ids': line, + 'journal_id': journal.id, + 'date': date, + 'narration': inv.comment, + } + ctx['company_id'] = inv.company_id.id + ctx['invoice'] = inv + ctx_nolang = ctx.copy() + ctx_nolang.pop('lang', None) + move = account_move.with_context(ctx_nolang).create(move_vals) + # Pass invoice in context in method post: used if you want to get the same + # account move reference when creating the same invoice after a cancelled one: + move.post() + # make the invoice point to that move + vals = { + 'move_id': move.id, + 'date': date, + 'move_name': move.name, + } + inv.with_context(ctx).write(vals) + return True + + def finalize_invoice_move_lines(self, move_lines): + res = super(AccountMove, self).\ + finalize_invoice_move_lines(move_lines) + parcela = 1 + for line in move_lines: + if 'name' in line[2]: + for inv in self: + if inv.parcela_ids: + pm = inv.parcela_ids[parcela-1].payment_mode_id.id + parc = str(parcela).zfill(2) + if line[2]['name'] == parc: + line[2]['payment_mode_id'] = pm + parcela += 1 + return res + +class InvoiceParcela(models.Model): + _name = 'invoice.parcela' + _order = 'data_vencimento' + + move_id = fields.Many2one('account.move', string="Fatura") + currency_id = fields.Many2one( + 'res.currency', related='move_id.currency_id', + string="EDoc Currency", readonly=True) + numero_fatura = fields.Char(string=u"Número Fatura", size=60) + data_vencimento = fields.Date(string="Data Vencimento") + valor = fields.Monetary(string="Valor Parcela") + payment_mode_id = fields.Many2one( + 'account.payment.mode', string=u"Modo de pagamento") diff --git a/payment_installment/security/ir.model.access.csv b/payment_installment/security/ir.model.access.csv new file mode 100644 index 00000000..1c2ad273 --- /dev/null +++ b/payment_installment/security/ir.model.access.csv @@ -0,0 +1,3 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"acess_invoice_parcelas","payment.install","model_invoice_parcela","l10n_br_fiscal.group_user",1,1,1,1 + diff --git a/payment_installment/views/payment_installment.xml b/payment_installment/views/payment_installment.xml new file mode 100644 index 00000000..89fd6e2f --- /dev/null +++ b/payment_installment/views/payment_installment.xml @@ -0,0 +1,56 @@ + + + + + view.payment.installment.form + account.move + + + + + + + + + + + + + +