class Servico(models.Model): _description = 'Serviço' _name = 'sped.servico' _order = 'codigo' _rec_name = 'servico' codigo = fields.Char('Código', size=4, required=True, index=True) descricao = fields.NameChar('Descrição', size=400, required=True, index=True) codigo_municipio = fields.Char('Código no município', size=9) #cest_ids = fields.Many2many('sped.cest', 'tabela_servico_cest', 'servico_id', 'cest_id', 'Códigos CEST') al_iss_ids = fields.One2many('sped.aliquota.iss', 'servico_id', 'Alíquotas de ISS') @api.one @api.depends('codigo', 'descricao') def _servico(self): self.codigo_formatado = self.codigo[:2] + '.' + self.codigo[2:] self.servico = self.codigo_formatado self.servico += ' - ' + self.descricao[:60] codigo_formatado = fields.Char(string='Servico', compute=_servico, store=True) servico = fields.Char(string='Servico', compute=_servico, store=True) def _valida_codigo(self): valores = {} res = {'value': valores} if (not self.codigo): return res if self.id: servico_ids = self.search([('codigo', '=', self.codigo), ('id', '!=', self.id)]) else: servico_ids = self.search([('codigo', '=', self.codigo)]) if len(servico_ids) > 0: raise ValidationError('Código já existe na tabela!') return res @api.one @api.constrains('codigo') def constrains_codigo(self): self._valida_codigo() @api.onchange('codigo') def onchange_codigo(self): return self._valida_codigo()
class Pais(models.Model): _description = 'País' _name = 'sped.pais' _rec_name = 'nome' _order = 'nome' _inherits = {'res.country': 'country_id'} country_id = fields.Many2one('res.country', 'Country original', ondelete='restrict', required=True) codigo_bacen = fields.Char('Código BANCO CENTRAL', size=4, index=True) codigo_siscomex = fields.Char('Código SISCOMEX', size=3) nome = fields.NameChar('Nome', size=60, index=True) iso_3166_alfa_2 = fields.Char('Código ISO 3166', size=2, index=True)
class NCM(models.Model): _description = 'NCM' _name = 'sped.ncm' _order = 'codigo, ex' _rec_name = 'ncm' codigo = fields.Char('Código', size=8, required=True, index=True) ex = fields.Char('EX', size=2, index=True) descricao = fields.NameChar('Descrição', size=255, required=True, index=True) al_ipi_id = fields.Many2one('sped.aliquota.ipi', string='Alíquota do IPI') #cest_ids = fields.Many2many('sped.cest', 'sped_ncm_cest', 'ncm_id', 'cest_id', 'Códigos CEST') @api.one @api.depends('codigo', 'ex', 'descricao', 'al_ipi_id') def _ncm(self): self.codigo_formatado = self.codigo[:2] + '.' + self.codigo[2:4] + '.' + self.codigo[4:6] + '.' + self.codigo[6:] self.ncm = self.codigo_formatado if self.ex: self.ncm += '-ex' + self.ex self.ncm += ' - ' + self.descricao[:60] codigo_formatado = fields.Char(string='NCM', compute=_ncm, store=True) ncm = fields.Char(string='NCM', compute=_ncm, store=True) def _valida_codigo(self): valores = {} res = {'value': valores} if (not self.codigo) and (not self.ex): return res if self.id: ncm_ids = self.search([('codigo', '=', self.codigo), ('ex', '=', self.ex), ('id', '!=', self.id)]) else: ncm_ids = self.search([('codigo', '=', self.codigo), ('ex', '=', self.ex)]) if len(ncm_ids) > 0: raise ValidationError('Código já existe na tabela!') return res @api.one @api.constrains('codigo', 'ex') def constrains_codigo(self): self._valida_codigo() @api.onchange('codigo', 'ex') def onchange_codigo(self): return self._valida_codigo()
class nbs(models.Model): _description = 'nbs' _name = 'sped.nbs' _order = 'codigo' _rec_name = 'nbs' codigo = fields.Char('Código', size=9, required=True, index=True) descricao = fields.NameChar('Descrição', size=255, required=True, index=True) @api.one @api.depends('codigo', 'descricao') def _nbs(self): self.codigo_formatado = self.codigo[0] + '.' + self.codigo[ 1:5] + '.' + self.codigo[5:7] + '.' + self.codigo[7:] self.nbs = self.codigo_formatado + ' - ' + self.descricao[:60] codigo_formatado = fields.Char(string='nbs', compute=_nbs, store=True) nbs = fields.Char(string='nbs', compute=_nbs, store=True) def _valida_codigo(self): valores = {} res = {'value': valores} if (not self.codigo): return res if self.id: nbs_ids = self.search([('codigo', '=', self.codigo), ('id', '!=', self.id)]) else: nbs_ids = self.search([('codigo', '=', self.codigo)]) if len(nbs_ids) > 0: raise ValidationError('Código já existe na tabela!') return res @api.one @api.constrains('codigo') def constrains_codigo(self): self._valida_codigo() @api.onchange('codigo') def onchange_codigo(self): return self._valida_codigo()
class Documento(models.Model): _description = 'Documento Fiscal' _name = 'sped.documento' _order = 'emissao, modelo, data_emissao desc, serie, numero' _rec_name = 'numero' empresa_id = fields.Many2one('sped.empresa', 'Empresa', ondelete='restrict', default=lambda self: self.env['sped.empresa']. _empresa_ativa('sped.documento')) empresa_cnpj_cpf = fields.Char('CNPJ/CPF', size=18, related='empresa_id.cnpj_cpf', readonly=True) #company_id = fields.Many2one('res.company', 'Empresa', ondelete='restrict', store=True, related='empresa_id.original_company_id') #company_id = fields.Many2one('res.company', 'Empresa', ondelete='restrict', default=lambda self: self.env['res.company']._company_default_get('sped.documento')) emissao = fields.Selection(TIPO_EMISSAO, 'Tipo de emissão', index=True) modelo = fields.Selection(MODELO_FISCAL, 'Modelo', index=True) data_hora_emissao = fields.Datetime('Data de emissão', index=True, default=fields.Datetime.now) data_hora_entrada_saida = fields.Datetime('Data de entrada/saída', index=True, default=fields.Datetime.now) @api.one @api.depends('data_hora_emissao', 'data_hora_entrada_saida') def _data_hora_separadas(self): data_hora_emissao = data_hora_horario_brasilia( parse_datetime(self.data_hora_emissao)) self.data_emissao = str(data_hora_emissao)[:10] self.hora_emissao = str(data_hora_emissao)[11:19] data_hora_entrada_saida = data_hora_horario_brasilia( parse_datetime(self.data_hora_entrada_saida)) self.data_entrada_saida = str(data_hora_entrada_saida)[:10] self.hora_entrada_saida = str(data_hora_entrada_saida)[11:19] data_emissao = fields.Date('Data de emissão', compute=_data_hora_separadas, store=True, index=True) hora_emissao = fields.Char('Hora de emissão', size=8, compute=_data_hora_separadas, store=True) data_entrada_saida = fields.Date('Data de entrada/saída', compute=_data_hora_separadas, store=True, index=True) hora_entrada_saida = fields.Char('Hora de entrada/saída', size=8, compute=_data_hora_separadas, store=True) serie = fields.Char('Série', index=True) numero = fields.Numero('Número', index=True) entrada_saida = fields.Selection(ENTRADA_SAIDA, 'Entrada/Saída', index=True, default=ENTRADA_SAIDA_SAIDA) situacao_fiscal = fields.Selection(SITUACAO_FISCAL, 'Situação fiscal', index=True, default=SITUACAO_FISCAL_REGULAR) ambiente_nfe = fields.Selection(AMBIENTE_NFE, 'Ambiente da NF-e', index=True, default=AMBIENTE_NFE_HOMOLOGACAO) tipo_emissao_nfe = fields.Selection(TIPO_EMISSAO_NFE, 'Tipo de emissão da NF-e', default=TIPO_EMISSAO_NFE_NORMAL) ie_st = fields.Char('IE do substituto tributário', size=14) municipio_fato_gerador_id = fields.Many2one('sped.municipio', 'Município do fato gerador') operacao_id = fields.Many2one('sped.operacao', 'Operação', ondelete='restrict') # # Campos da operação # regime_tributario = fields.Selection(REGIME_TRIBUTARIO, 'Regime tributário', default=REGIME_TRIBUTARIO_SIMPLES) forma_pagamento = fields.Selection(FORMA_PAGAMENTO, 'Forma de pagamento', default=FORMA_PAGAMENTO_A_VISTA) finalidade_nfe = fields.Selection(FINALIDADE_NFE, 'Finalidade da NF-e', default=FINALIDADE_NFE_NORMAL) consumidor_final = fields.Selection(TIPO_CONSUMIDOR_FINAL, 'Tipo do consumidor', default=TIPO_CONSUMIDOR_FINAL_NORMAL) presenca_comprador = fields.Selection( INDICADOR_PRESENCA_COMPRADOR, 'Presença do comprador', default=INDICADOR_PRESENCA_COMPRADOR_NAO_SE_APLICA) modalidade_frete = fields.Selection(MODALIDADE_FRETE, 'Modalidade do frete', default=MODALIDADE_FRETE_DESTINATARIO) natureza_operacao_id = fields.Many2one('sped.natureza.operacao', 'Natureza da operação', ondelete='restrict') infadfisco = fields.Text('Informações adicionais de interesse do fisco') infcomplementar = fields.Text('Informações complementares') deduz_retencao = fields.Boolean('Deduz retenção do total da NF?', default=True) pis_cofins_retido = fields.Boolean('PIS-COFINS retidos?') al_pis_retido = fields.Porcentagem('Alíquota do PIS', default=0.65) al_cofins_retido = fields.Porcentagem('Alíquota da COFINS', default=3) csll_retido = fields.Boolean('CSLL retido?') al_csll = fields.Porcentagem('Alíquota da CSLL', default=1) limite_retencao_pis_cofins_csll = fields.Dinheiro( 'Obedecer limite de faturamento para retenção de', default=5000) irrf_retido = fields.Boolean('IR retido?') irrf_retido_ignora_limite = fields.Boolean( 'IR retido ignora limite de R$ 10,00?') al_irrf = fields.Porcentagem('Alíquota do IR', default=1) previdencia_retido = fields.Boolean('INSS retido?') cnae_id = fields.Many2one('sped.cnae', 'CNAE') natureza_tributacao_nfse = fields.Selection(NATUREZA_TRIBUTACAO_NFSE, 'Natureza da tributação') servico_id = fields.Many2one('sped.servico', 'Serviço') cst_iss = fields.Selection(ST_ISS, 'CST ISS') # # Destinatário/Remetente # participante_id = fields.Many2one('sped.participante', 'Destinatário/Remetente', ondelete='restrict') participante_cnpj_cpf = fields.Char('CNPJ/CPF', size=18, related='participante_id.cnpj_cpf', readonly=True) participante_tipo_pessoa = fields.Char( 'Tipo pessoa', size=1, related='participante_id.tipo_pessoa', readonly=True) participante_razao_social = fields.NameChar( 'Razão Social', size=60, related='participante_id.razao_social', readonly=True) participante_fantasia = fields.NameChar('Fantasia', size=60, related='participante_id.fantasia', readonly=True) participante_endereco = fields.NameChar('Endereço', size=60, related='participante_id.endereco', readonly=True) participante_numero = fields.Char('Número', size=60, related='participante_id.numero', readonly=True) participante_complemento = fields.Char( 'Complemento', size=60, related='participante_id.complemento', readonly=True) participante_bairro = fields.NameChar('Bairro', size=60, related='participante_id.bairro', readonly=True) participante_municipio_id = fields.Many2one( 'sped.municipio', string='Município', related='participante_id.municipio_id', readonly=True) participante_cidade = fields.NameChar('Município', related='participante_id.cidade', readonly=True) participante_estado = fields.UpperChar('Estado', related='participante_id.estado', readonly=True) participante_cep = fields.Char('CEP', size=9, related='participante_id.cep', readonly=True) # # Telefone e email para a emissão da NF-e # participante_fone = fields.Char('Fone', size=18, related='participante_id.fone', readonly=True) participante_fone_comercial = fields.Char( 'Fone Comercial', size=18, related='participante_id.fone_comercial', readonly=True) participante_celular = fields.Char('Celular', size=18, related='participante_id.celular', readonly=True) participante_email = fields.Email('Email', size=60, related='participante_id.email', readonly=True) # # Inscrições e registros # participante_contribuinte = fields.Selection( IE_DESTINATARIO, string='Contribuinte', default='2', related='participante_id.contribuinte', readonly=True) participante_ie = fields.Char('Inscrição estadual', size=18, related='participante_id.ie', readonly=True) # # Chave e validação da chave # chave = fields.Char('Chave', size=44) # # Transporte # transportadora_id = fields.Many2one('res.partner', 'Transportadora', ondelete='restrict', domain=[('cnpj_cpf', '!=', False)]) veiculo_id = fields.Many2one('sped.veiculo', 'Veículo', ondelete='restrict') reboque_1_id = fields.Many2one('sped.veiculo', 'Reboque 1', ondelete='restrict') reboque_2_id = fields.Many2one('sped.veiculo', 'Reboque 2', ondelete='restrict') reboque_3_id = fields.Many2one('sped.veiculo', 'Reboque 3', ondelete='restrict') reboque_4_id = fields.Many2one('sped.veiculo', 'Reboque 4', ondelete='restrict') reboque_5_id = fields.Many2one('sped.veiculo', 'Reboque 5', ondelete='restrict') # # Totais dos itens # # Valor total dos produtos vr_produtos = fields.Dinheiro('Valor dos produtos/serviços') vr_produtos_tributacao = fields.Dinheiro( 'Valor dos produtos para tributação') vr_frete = fields.Dinheiro('Valor do frete') vr_seguro = fields.Dinheiro('Valor do seguro') vr_desconto = fields.Dinheiro('Valor do desconto') vr_outras = fields.Dinheiro('Outras despesas acessórias') vr_operacao = fields.Dinheiro('Valor da operação') vr_operacao_tributacao = fields.Dinheiro( 'Valor da operação para tributação') # ICMS próprio bc_icms_proprio = fields.Dinheiro('Base do ICMS próprio') vr_icms_proprio = fields.Dinheiro('Valor do ICMS próprio') # ICMS SIMPLES vr_icms_sn = fields.Dinheiro('Valor do crédito de ICMS - SIMPLES Nacional') vr_simples = fields.Dinheiro('Valor do SIMPLES Nacional') # ICMS ST bc_icms_st = fields.Dinheiro('Base do ICMS ST') vr_icms_st = fields.Dinheiro('Valor do ICMS ST') # ICMS ST retido bc_icms_st_retido = fields.Dinheiro( 'Base do ICMS retido anteriormente por substituição tributária') vr_icms_st_retido = fields.Dinheiro( 'Valor do ICMS retido anteriormente por substituição tributária') # IPI bc_ipi = fields.Dinheiro('Base do IPI') vr_ipi = fields.Dinheiro('Valor do IPI') # Imposto de importação bc_ii = fields.Dinheiro('Base do imposto de importação') vr_ii = fields.Dinheiro('Valor do imposto de importação') # PIS e COFINS bc_pis_proprio = fields.Dinheiro('Base do PIS próprio') vr_pis_proprio = fields.Dinheiro('Valor do PIS próprio') bc_cofins_proprio = fields.Dinheiro('Base da COFINS própria') vr_cofins_proprio = fields.Dinheiro('Valor do COFINS própria') bc_pis_st = fields.Dinheiro('Base do PIS ST') vr_pis_st = fields.Dinheiro('Valor do PIS ST') bc_cofins_st = fields.Dinheiro('Base da COFINS ST') vr_cofins_st = fields.Dinheiro('Valor do COFINS ST') # # Totais dos itens (grupo ISS) # # Valor total dos serviços vr_servicos = fields.Dinheiro('Valor dos serviços') # ISS bc_iss = fields.Dinheiro('Base do ISS') vr_iss = fields.Dinheiro('Valor do ISS') ### PIS e COFINS ###'vr_pis_servico = CampoDinheiro(u'PIS sobre serviços'), ##'vr_pis_servico = fields.Dinheiro('PIS sobre serviços'), ###'vr_cofins_servico = CampoDinheiro(u'COFINS sobre serviços'), ##'vr_cofins_servico = fields.Dinheiro('COFINS sobre serviços'), ### ### Retenções de tributos (órgãos públicos, substitutos tributários etc.) ### ###'vr_operacao_pis_cofins_csll = CampoDinheiro(u'Base da retenção do PIS-COFINS e CSLL'), ### PIS e COFINS ##'pis_cofins_retido = fields.boolean(u'PIS-COFINS retidos?'), ##'al_pis_retido = CampoPorcentagem(u'Alíquota do PIS retido'), ##'vr_pis_retido = CampoDinheiro(u'PIS retido'), ##'al_cofins_retido = CampoPorcentagem(u'Alíquota da COFINS retida'), ##'vr_cofins_retido = CampoDinheiro(u'COFINS retida'), ### Contribuição social sobre lucro líquido ##'csll_retido = fields.boolean(u'CSLL retida?'), ##'al_csll = CampoPorcentagem('Alíquota da CSLL'), ##'vr_csll = CampoDinheiro(u'CSLL retida'), ##'bc_csll_propria = CampoDinheiro(u'Base da CSLL própria'), ##'al_csll_propria = CampoPorcentagem('Alíquota da CSLL própria'), ##'vr_csll_propria = CampoDinheiro(u'CSLL própria'), ### IRRF ##'irrf_retido = fields.boolean(u'IR retido?'), ##'bc_irrf = CampoDinheiro(u'Base do IRRF'), ##'al_irrf = CampoPorcentagem(u'Alíquota do IRRF'), ##'vr_irrf = CampoDinheiro(u'Valor do IRRF'), ##'bc_irpj_proprio = CampoDinheiro(u'Valor do IRPJ próprio'), ##'al_irpj_proprio = CampoPorcentagem(u'Alíquota do IRPJ próprio'), ##'vr_irpj_proprio = CampoDinheiro(u'Valor do IRPJ próprio'), ### Previdência social ##'previdencia_retido = fields.boolean(u'INSS retido?'), ##'bc_previdencia = fields.Dinheiro('Base do INSS'), ##'al_previdencia = CampoPorcentagem(u'Alíquota do INSS'), ##'vr_previdencia = fields.Dinheiro('Valor do INSS'), ### ISS ##'iss_retido = fields.boolean(u'ISS retido?'), ##'bc_iss_retido = CampoDinheiro(u'Base do ISS'), ##'vr_iss_retido = CampoDinheiro(u'Valor do ISS'), ### ### Total da NF e da fatura (podem ser diferentes no caso de operação triangular) ### ###'vr_nf = CampoDinheiro(u'Valor total da NF'), ##'vr_nf = fields.Dinheiro('Valor total da NF'), ###'vr_fatura = CampoDinheiro(u'valor total da fatura'), ##'vr_fatura = fields.Dinheiro('Valor total da fatura'), ##'vr_ibpt = fields.Dinheiro('Valor IBPT'), item_ids = fields.One2many('sped.documento.item', 'documento_id', 'Itens') @api.onchange('empresa_id', 'modelo', 'emissao') def onchange_empresa_id(self): res = {} valores = {} res['value'] = valores if not self.empresa_id: return res if self.emissao != TIPO_EMISSAO_PROPRIA: return res if self.modelo not in (MODELO_FISCAL_NFE, MODELO_FISCAL_NFCE, MODELO_FISCAL_NFSE): return res if self.modelo == MODELO_FISCAL_NFE: valores['ambiente_nfe'] = self.empresa_id.ambiente_nfe valores['tipo_emissao_nfe'] = self.empresa_id.tipo_emissao_nfe if self.empresa_id.tipo_emissao_nfe == TIPO_EMISSAO_NFE_NORMAL: if self.empresa_id.ambiente_nfe == AMBIENTE_NFE_PRODUCAO: valores['serie'] = self.empresa_id.serie_nfe_producao else: valores['serie'] = self.empresa_id.serie_nfe_homologacao else: if self.empresa_id.ambiente_nfe == AMBIENTE_NFE_PRODUCAO: valores[ 'serie'] = self.empresa_id.serie_nfe_contingencia_producao else: valores[ 'serie'] = self.empresa_id.serie_nfe_contingencia_homologacao elif self.modelo == MODELO_FISCAL_NFCE: valores['ambiente_nfe'] = self.empresa_id.ambiente_nfce valores['tipo_emissao_nfe'] = self.empresa_id.tipo_emissao_nfce if self.empresa_id.tipo_emissao_nfce == TIPO_EMISSAO_NFE_NORMAL: if self.empresa_id.ambiente_nfce == AMBIENTE_NFE_PRODUCAO: valores['serie'] = self.empresa_id.serie_nfce_producao else: valores['serie'] = self.empresa_id.serie_nfce_homologacao else: if self.empresa_id.ambiente_nfce == AMBIENTE_NFE_PRODUCAO: valores[ 'serie'] = self.empresa_id.serie_nfce_contingencia_producao else: valores[ 'serie'] = self.empresa_id.serie_nfce_contingencia_homologacao elif self.modelo == MODELO_FISCAL_NFSE: valores['ambiente_nfe'] = self.empresa_id.ambiente_nfse valores['tipo_emissao_nfe'] = TIPO_EMISSAO_NFE_NORMAL if self.empresa_id.ambiente_nfse == AMBIENTE_NFE_PRODUCAO: valores['serie_rps'] = self.empresa_id.serie_rps_producao else: valores['serie_rps'] = self.empresa_id.serie_rps_homologacao return res @api.onchange('operacao_id', 'emissao', 'natureza_operacao_id') def onchange_operacao_id(self): res = {} valores = {} res['value'] = valores if not self.operacao_id: return res valores['modelo'] = self.operacao_id.modelo valores['emissao'] = self.operacao_id.emissao valores['entrada_saida'] = self.operacao_id.entrada_saida if self.emissao == TIPO_EMISSAO_PROPRIA: if self.operacao_id.natureza_operacao_id: valores[ 'natureza_operacao_id'] = self.operacao_id.natureza_operacao_id.id if self.operacao_id.serie: valores['serie'] = self.operacao_id.serie valores['regime_tributario'] = self.operacao_id.regime_tributario valores['forma_pagamento'] = self.operacao_id.forma_pagamento valores['finalidade_nfe'] = self.operacao_id.finalidade_nfe valores['modalidade_frete'] = self.operacao_id.modalidade_frete valores['infadfisco'] = self.operacao_id.infadfisco valores['infcomplementar'] = self.operacao_id.infcomplementar valores['deduz_retencao'] = self.operacao_id.deduz_retencao valores['pis_cofins_retido'] = self.operacao_id.pis_cofins_retido valores['al_pis_retido'] = self.operacao_id.al_pis_retido valores['al_cofins_retido'] = self.operacao_id.al_cofins_retido valores['csll_retido'] = self.operacao_id.csll_retido valores['al_csll'] = self.operacao_id.al_csll valores[ 'limite_retencao_pis_cofins_csll'] = self.operacao_id.limite_retencao_pis_cofins_csll valores['irrf_retido'] = self.operacao_id.irrf_retido valores[ 'irrf_retido_ignora_limite'] = self.operacao_id.irrf_retido_ignora_limite valores['al_irrf'] = self.operacao_id.al_irrf valores['previdencia_retido'] = self.operacao_id.previdencia_retido valores['consumidor_final'] = self.operacao_id.consumidor_final valores['presenca_comprador'] = self.operacao_id.presenca_comprador if self.operacao_id.cnae_id: valores['cnae_id'] = self.operacao_id.cnae_id.id valores[ 'natureza_tributacao_nfse'] = self.operacao_id.natureza_tributacao_nfse if self.operacao_id.servico_id: valores['servico_id'] = self.operacao_id.servico_id.id valores['cst_iss'] = self.operacao_id.cst_iss return res @api.onchange('empresa_id', 'modelo', 'emissao', 'serie', 'ambiente_nfe') def onchange_serie(self): res = {} valores = {} res['value'] = valores if not self.empresa_id: return res if self.emissao != TIPO_EMISSAO_PROPRIA: return res if self.modelo not in (MODELO_FISCAL_NFE, MODELO_FISCAL_NFCE): return res ultimo_numero = self.search([ ('empresa_id.cnpj_cpf', '=', self.empresa_id.cnpj_cpf), ('ambiente_nfe', '=', self.ambiente_nfe), ('emissao', '=', self.emissao), ('modelo', '=', self.modelo), ('serie', '=', self.serie.strip()), ], limit=1, order='numero desc') valores['serie'] = self.serie.strip() if len(ultimo_numero) == 0: valores['numero'] = 1 else: valores['numero'] = ultimo_numero[0].numero + 1 return res @api.depends('consumidor_final') @api.onchange('participante_id') def onchange_participante_id(self): res = {} valores = {} res['value'] = valores # # Quando o tipo da nota for para consumidor normal, mas o participante não é # contribuinte, define que ele é consumidor final, exceto em caso de operação # com estrangeiros # if self.consumidor_final == TIPO_CONSUMIDOR_FINAL_NORMAL: if self.participante_id.estado != 'EX': if self.participante_id.contribuinte != INDICADOR_IE_DESTINATARIO: valores[ 'consumidor_final'] = TIPO_CONSUMIDOR_FINAL_CONSUMIDOR_FINAL return res
class CEST(models.Model): _description = 'CEST' _name = 'sped.cest' _order = 'codigo' _rec_name = 'cest' codigo = fields.Char('Código', size=7, required=True, index=True) descricao = fields.NameChar('Descrição', size=1500, required=True, index=True) @api.one @api.depends('codigo', 'descricao') def _cest(self): self.codigo_formatado = self.codigo[:2] + '.' + self.codigo[ 2:5] + '.' + self.codigo[5:] self.cest = self.codigo_formatado self.cest += ' - ' + self.descricao[:60] codigo_formatado = fields.Char(string='CEST', compute=_cest, store=True) cest = fields.Char(string='CEST', compute=_cest, store=True) #_sql_constraints = [ #('codigo_unique', 'unique (codigo)', u'O código não pode se repetir!'), #] #def name_search(self, cr, uid, name, args=[], operator='ilike', context={}, limit=100): #if name and operator in ('=', 'ilike', '=ilike', 'like'): #if operator != '=': #name = name.strip().replace(' ', '%') #ids = self.search(cr, uid, [ #'|', #('codigo', '=', name), #('descricao', 'ilike', name), #] + args, limit=limit, context=context) #if ids: #return self.name_get(cr, uid, ids, context) #return super(CEST, self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit) def _valida_codigo(self): valores = {} res = {'value': valores} if not self.codigo: return res if self.id: cest_ids = self.search([('codigo', '=', self.codigo), ('id', '!=', self.id)]) else: cest_ids = self.search([('codigo', '=', self.codigo)]) if len(cest_ids) > 0: raise ValidationError(u'Código já existe na tabela!') return res @api.one @api.constrains('codigo') def constrains_codigo(self): self._valida_codigo() @api.onchange('codigo') def onchange_codigo(self): return self._valida_codigo()
class Unidade(models.Model): _description = 'Unidade de medida' #_inherits = {'product.uom': 'uom_id'} _name = 'sped.unidade' _order = 'codigo_unico' _rec_name = 'codigo' #uom_id = fields.Many2one('product.uom', 'UOM original', ondelete='restrict', required=True) TIPO_UNIDADE_UNIDADE = 'U' TIPO_UNIDADE_PESO = 'P' TIPO_UNIDADE_VOLUME = 'V' TIPO_UNIDADE_COMPRIMENTO = 'C' TIPO_UNIDADE_AREA = 'A' TIPO_UNIDADE_TEMPO = 'T' TIPO_UNIDADE_EMBALAGEM = 'E' tipo = fields.Selection(TIPO_UNIDADE, string=u'Tipo', required=True, index=True) codigo = fields.Char(string=u'Código', size=10, index=True) codigo_unico = fields.LowerChar(string=u'Código', size=10, index=True, compute='_codigo_unico', store=True) @api.one @api.depends('codigo') def _codigo_unico(self): self.codigo_unico = self.codigo.lower().strip().replace(' ', ' ').replace('²', '2').replace('³', '3') if self.codigo else False def _valida_codigo(self): valores = {} res = {'value': valores} if self.codigo: sql = u""" select u.id from sped_unidade u where lower(unaccent(u.codigo_unico)) = lower(unaccent('{codigo}')) """ sql = sql.format(codigo=self.codigo.lower().strip().replace(' ', ' ')) if self.id or self._origin.id: sql += u""" and u.id != {id} """ sql = sql.format(id=self.id or self._origin.id) self.env.cr.execute(sql) jah_existe = self.env.cr.fetchall() if jah_existe: raise ValidationError(u'Unidade de medida já existe!') return res @api.one @api.constrains('codigo') def constrains_codigo(self): self._valida_codigo() @api.onchange('codigo') def onchange_codigo(self): return self._valida_codigo() nome = fields.NameChar(string=u'Nome', size=60, index=True) nome_unico = fields.LowerChar(string=u'Nome', size=60, index=True, compute='_nome_unico', store=True) @api.one @api.depends('nome') def _nome_unico(self): self.nome_unico = self.nome.lower().strip().replace(' ', ' ') if self.nome else False def _valida_nome(self): valores = {} res = {'value': valores} if self.nome: sql = u""" select u.id from sped_unidade u where lower(unaccent(u.nome_unico)) = lower(unaccent('{nome}')) """ sql = sql.format(nome=self.nome.lower().strip().replace(' ', ' ')) if self.id or self._origin.id: sql += u""" and u.id != {id} """ sql = sql.format(id=self.id or self._origin.id) self.env.cr.execute(sql) jah_existe = self.env.cr.fetchall() if jah_existe: raise ValidationError(u'Nome da unidade de medida já existe!') return res @api.one @api.constrains('nome') def constrains_nome(self): self._valida_nome() @api.onchange('nome') def onchange_nome(self): return self._valida_nome() fator_relacao_decimal = fields.Float(u'Multiplica por', default=10, digits=(18, 6)) precisao_decimal = fields.Float(u'Elevado a', default=2, digits=(18, 6)) arredondamento = fields.Integer(u'Casas decimais para arredondamento', default=0) nome_singular = fields.LowerChar(string=u'Singular', size=60) nome_plural = fields.LowerChar(string=u'Plural', size=60) genero_masculino = fields.Boolean(string=u'Nome é masculino?', default=True) usa_meio = fields.Boolean(string=u'Usa meio?', default=False) usa_virgula = fields.Boolean(string=u'Usa vírgula?', default=True) subunidade_id = fields.Many2one('sped.unidade', string=u'Unidade decimal', ondelete='restrict') @api.one def extenso(self, numero=D(0)): parametros = { 'numero': numero, 'unidade': ('unidade', 'unidades'), 'genero_unidade_masculino': False, 'precisao_decimal': self.precisao_decimal, 'unidade_decimal': ('subunidade', 'subunidades'), 'genero_unidade_decimal_masculino': False, 'mascara_negativo': ('menos %s', 'menos %s'), 'fator_relacao_decimal': self.fator_relacao_decimal or 10, 'usa_meio': self.usa_meio, 'usa_fracao': False, 'usa_virgula': self.usa_virgula, } if self.usa_virgula: parametros['fator_relacao_decimal'] = 10 parametros['precisao_decimal'] = 2 if self.nome_singular and self.nome_plural: parametros['unidade'] = (self.nome_singular, self.nome_plural) parametros['genero_unidade_masculino'] = self.genero_masculino if self.subunidade_id and self.subunidade_id.nome_singular and self.subunidade_id.nome_plural: parametros['unidade_decimal'] = (self.subunidade_id.nome_singular, self.subunidade_id.nome_plural) parametros['genero_unidade_decimal_masculino'] = self.subunidade_id.genero_masculino return valor_por_extenso_unidade(**parametros) @api.one @api.depends('nome_singular', 'nome_plural', 'genero_masculino', 'usa_meio', 'subunidade_id', 'usa_virgula', 'fator_relacao_decimal', 'precisao_decimal') def _extenso(self): parametros = { 'numero': 0, 'unidade': ('unidade', 'unidades'), 'genero_unidade_masculino': False, 'precisao_decimal': 0, 'unidade_decimal': ('subunidade', 'subunidades'), 'genero_unidade_decimal_masculino': False, 'mascara_negativo': ('menos %s', 'menos %s'), 'fator_relacao_decimal': self.fator_relacao_decimal or 10, 'usa_meio': self.usa_meio, 'usa_fracao': False, 'usa_virgula': self.usa_virgula, } if self.nome_singular and self.nome_plural: parametros['unidade'] = (self.nome_singular, self.nome_plural) parametros['genero_unidade_masculino'] = self.genero_masculino if self.subunidade_id and self.subunidade_id.nome_singular and self.subunidade_id.nome_plural: parametros['unidade_decimal'] = (self.subunidade_id.nome_singular, self.subunidade_id.nome_plural) parametros['genero_unidade_decimal_masculino'] = self.subunidade_id.genero_masculino self.extenso_zero = valor_por_extenso_unidade(**parametros) parametros['numero'] = D('1') self.extenso_singular_inteiro = valor_por_extenso_unidade(**parametros) parametros['numero'] = D('1234567') self.extenso_plural_inteiro = valor_por_extenso_unidade(**parametros) parametros['precisao_decimal'] = self.precisao_decimal or 0 if self.usa_virgula: parametros['fator_relacao_decimal'] = 10 parametros['precisao_decimal'] = 2 if self.usa_meio or self.subunidade_id or self.usa_virgula: parametros['numero'] = D('1.5') self.extenso_singular_meio = valor_por_extenso_unidade(**parametros) else: self.extenso_singular_meio = self.extenso_singular_inteiro if self.subunidade_id or self.usa_virgula: parametros['numero'] = D('1.01') self.extenso_singular_um_decimo = valor_por_extenso_unidade(**parametros) parametros['numero'] = D('1.67') self.extenso_singular_decimal = valor_por_extenso_unidade(**parametros) parametros['numero'] = D('1234567.89') self.extenso_plural_decimal = valor_por_extenso_unidade(**parametros) else: self.extenso_singular_um_decimo = self.extenso_singular_inteiro self.extenso_singular_decimal = self.extenso_singular_inteiro self.extenso_plural_decimal = self.extenso_plural_inteiro extenso_zero = fields.Char(string=u'Ex. 0', compute=_extenso) extenso_singular_inteiro = fields.Char(string=u'Ex. 1', compute=_extenso) extenso_plural_inteiro = fields.Char(string=u'Ex. 1.234.567', compute=_extenso) extenso_singular_um_decimo = fields.Char(string=u'Ex. 1,01', compute=_extenso) extenso_singular_meio = fields.Char(string=u'Ex. 1,50', compute=_extenso) extenso_singular_decimal = fields.Char(string=u'Ex. 1,67', compute=_extenso) extenso_plural_decimal = fields.Char(string=u'Ex. 1.234.567,89', compute=_extenso) _sql_constraints = [ ('codigo_unique', 'unique(codigo_unico)', u'Código da unidade de medida não pode se repetir'), ('nome_unique', 'unique(nome_unico)', u'Nome da unidade de medida não pode se repetir'), ] @api.model def name_search(self, name='', args=[], operator='ilike', limit=100): if name and operator in ('=', 'ilike', '=ilike', 'like'): #if operator != '=': #name = name.strip().replace(' ', '%') name = name.replace('²', '2') name = name.replace('³', '3') args += [['codigo_unico', 'ilike', name]] print(name, args) return super(Unidade, self).name_search(name=name, args=args, operator=operator, limit=limit)
class OperacaoFiscal(models.Model): _description = 'Operações Fiscais' _name = 'sped.operacao' _order = 'emissao, modelo, nome' _rec_name = 'nome' empresa_id = fields.Many2one('sped.empresa', 'Empresa', ondelete='restrict') #company_id = fields.Many2one('res.company', 'Empresa', ondelete='restrict') modelo = fields.Selection(MODELO_FISCAL, 'Modelo', required=True, index=True, default=MODELO_FISCAL_NFE) emissao = fields.Selection(TIPO_EMISSAO, 'Tipo de emissão', index=True, default=TIPO_EMISSAO_PROPRIA) entrada_saida = fields.Selection(ENTRADA_SAIDA, 'Entrada/saída', index=True, default=ENTRADA_SAIDA_SAIDA) nome = fields.NameChar(string='Nome', size=120, index=True) codigo = fields.Char(string='Código', size=60, index=True) serie = fields.Char('Série', size=3) regime_tributario = fields.Selection(REGIME_TRIBUTARIO, 'Regime tributário', default=REGIME_TRIBUTARIO_SIMPLES) forma_pagamento = fields.Selection(FORMA_PAGAMENTO, 'Forma de pagamento', default=FORMA_PAGAMENTO_A_VISTA) finalidade_nfe = fields.Selection(FINALIDADE_NFE, 'Finalidade da NF-e', default=FINALIDADE_NFE_NORMAL) modalidade_frete = fields.Selection(MODALIDADE_FRETE, 'Modalidade do frete', default=MODALIDADE_FRETE_DESTINATARIO) natureza_operacao_id = fields.Many2one('sped.natureza.operacao', 'Natureza da operação', ondelete='restrict') infadfisco = fields.Text('Informações adicionais de interesse do fisco') infcomplementar = fields.Text('Informações complementares') # # Retenção de impostos # deduz_retencao = fields.Boolean('Deduz retenção do total da NF?', default=True) pis_cofins_retido = fields.Boolean('PIS-COFINS retidos?') al_pis_retido = fields.Porcentagem('Alíquota do PIS', default=0.65) al_cofins_retido = fields.Porcentagem('Alíquota da COFINS', default=3) csll_retido = fields.Boolean('CSLL retido?') al_csll = fields.Porcentagem('Alíquota da CSLL', default=1) limite_retencao_pis_cofins_csll = fields.Dinheiro( 'Obedecer limite de faturamento para retenção de', default=5000) irrf_retido = fields.Boolean('IR retido?') irrf_retido_ignora_limite = fields.Boolean( 'IR retido ignora limite de R$ 10,00?') al_irrf = fields.Porcentagem('Alíquota do IR', default=1) # # Notas de serviço # previdencia_retido = fields.Boolean('INSS retido?') cnae_id = fields.Many2one('sped.cnae', 'CNAE') natureza_tributacao_nfse = fields.Selection(NATUREZA_TRIBUTACAO_NFSE, 'Natureza da tributação') servico_id = fields.Many2one('sped.servico', 'Serviço') cst_iss = fields.Selection(ST_ISS, 'CST ISS') #'prioriza_familia_ncm': fields.boolean('Prioriza família tributária por NCM?'), #'user_ids': fields.many2many('res.users', 'sped_operacao_usuario', 'sped_operacao_id', 'res_user_id', 'Usuários permitidos'), #'company_ids': fields.many2many('res.company', 'sped_operacao_company', 'sped_operacao_id', 'company_id', 'Empresas permitidas'), #'forca_recalculo_st_compra': fields.boolean('Força recálculo do ST na compra?'), #'operacao_entrada_id': fields.many2one('sped.operacao', 'Operação de entrada equivalente'), consumidor_final = fields.Selection(TIPO_CONSUMIDOR_FINAL, 'Tipo do consumidor', default=TIPO_CONSUMIDOR_FINAL_NORMAL) presenca_comprador = fields.Selection( INDICADOR_PRESENCA_COMPRADOR, 'Presença do comprador', default=INDICADOR_PRESENCA_COMPRADOR_NAO_SE_APLICA)
class Produto(models.Model): _description = 'Produtos e serviços' #_inherits = {'product.product': 'product_id'} _inherit = 'mail.thread' _name = 'sped.produto' _order = 'codigo, nome' _rec_name = 'nome' #product_id = fields.Many2one('product.product', 'Product original', ondelete='restrict', required=True) #company_id = fields.Many2one('res.company', string='Empresa', ondelete='restrict') nome = fields.NameChar(string='Nome', size=120, index=True) codigo = fields.Char(string='Código', size=60, index=True) codigo_barras = fields.Char(string='Código de barras', size=14, index=True) marca = fields.NameChar(string='Marca', size=60) foto = fields.Binary('Foto', attachment=True) preco_venda = fields.Unitario('Preço de venda') preco_custo = fields.Unitario('Preço de custo') peso_bruto = fields.Quantidade('Peso bruto') peso_liquido = fields.Quantidade('Peso líquido') tipo = fields.Selection(TIPO_PRODUTO_SERVICO, string='Tipo', index=True) org_icms = fields.Selection(ORIGEM_MERCADORIA, string='Origem da mercadoria', default='0') ncm_id = fields.Many2one('sped.ncm', 'NCM') cest_ids = fields.Many2many('sped.cest', related='ncm_id.cest_ids', string='Códigos CEST') exige_cest = fields.Boolean('Exige código CEST?') cest_id = fields.Many2one('sped.cest', 'CEST') protocolo_id = fields.Many2one('sped.protocolo.icms', 'Protocolo/Convênio') al_ipi_id = fields.Many2one('sped.aliquota.ipi', 'Alíquota de IPI') al_pis_cofins_id = fields.Many2one('sped.aliquota.pis.cofins', 'Alíquota de PIS e COFINS') servico_id = fields.Many2one('sped.servico', 'Código do serviço') nbs_id = fields.Many2one('sped.nbs', 'NBS') unidade_id = fields.Many2one('sped.unidade', 'Unidade') def _valida_codigo_barras(self): valores = {} res = {'value': valores} if self.codigo_barras: if (not valida_ean(self.codigo_barras)): raise ValidationError('Código de barras inválido!') valores['codigo_barras'] = self.codigo_barras return res @api.one @api.constrains('codigo_barras') def constrains_codigo_barras(self): self._valida_codigo_barras() @api.onchange('codigo_barras') def onchange_codigo_barras(self): return self._valida_codigo_barras() @api.onchange('ncm_id') def onchange_ncm(self): if len(self.ncm_id.cest_ids) == 1: return { 'value': { 'cest_id': self.ncm_ids.cest_ids[0].id, 'exige_cest': True } } elif len(self.ncm_id.cest_ids) > 1: return {'value': {'cest_id': False, 'exige_cest': True}} else: return {'value': {'cest_id': False, 'exige_cest': False}}
class CNAE(models.Model): _description = 'CNAE' _name = 'sped.cnae' _order = 'codigo' _rec_name = 'cnae' codigo = fields.Char('Código', size=7, required=True, index=True) descricao = fields.NameChar('Descrição', size=255, required=True, index=True) @api.one @api.depends('codigo', 'descricao') def _cnae(self): self.cnae = self.codigo[:4] + '-' + self.codigo[4] + '/' + self.codigo[ 5:] self.cnae += ' - ' + self.descricao cnae = fields.Char(string='CNAE', compute=_cnae, store=True) #_sql_constraints = [ #('codigo_unique', 'unique (codigo)', u'O código não pode se repetir!'), #] @api.model def name_search(self, name='', args=[], operator='ilike', limit=100): if name and operator in ('=', 'ilike', '=ilike', 'like'): if operator != '=': name = name.strip().replace(' ', '%') args += ['|', ('codigo', '=', name), ('descricao', 'ilike', name)] return super(CNAE, self).name_search(name=name, args=args, operator=operator, limit=limit) def _valida_codigo(self): valores = {} res = {'value': valores} if not self.codigo: return res if self.id: cnae_ids = self.search([('codigo', '=', self.codigo), ('id', '!=', self.id)]) else: cnae_ids = self.search([('codigo', '=', self.codigo)]) if len(cnae_ids) > 0: raise ValidationError(u'Código já existe na tabela!') return res @api.one @api.constrains('codigo') def constrains_codigo(self): self._valida_codigo() @api.onchange('codigo') def onchange_codigo(self): return self._valida_codigo()