syncra_addons/i18n_ao_nif_validator/models/res_partner.py

139 lines
5.6 KiB
Python

# -*- coding: utf-8 -*-
import requests
import re
import urllib3
import logging
from datetime import datetime
from odoo import models, fields, api, _
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class ResPartner(models.Model):
_inherit = 'res.partner'
# 1. CAMPOS
nif_ao = fields.Char(string="NIF Angola", copy=False)
nif_ao_validated = fields.Boolean(string="NIF Validado", default=False, copy=False, readonly=True)
nif_ao_state = fields.Char(string="Estado Fiscal (AGT)", readonly=True)
nif_ao_contributor_type = fields.Char(string="Tipo de Contribuinte", readonly=True)
nif_ao_inadimplente = fields.Char(string="Inadimplente", readonly=True)
nif_ao_regime_iva = fields.Char(string="Regime de IVA", readonly=True)
nif_ao_last_validation = fields.Datetime(string="Última Validação", readonly=True)
nif_ao_validation_count = fields.Integer(string="Consultas", compute='_compute_nif_logs_count')
# Contagem dos logs para mostrar no botão inteligente
def _compute_nif_logs_count(self):
for record in self:
if self.env.get('nif.validation.log'):
record.nif_ao_validation_count = self.env['nif.validation.log'].search_count([
('partner_id', '=', record.id)
])
else:
record.nif_ao_validation_count = 0
# Abre a janela do histórico
def action_open_nif_logs(self):
self.ensure_one()
return {
'name': _('Logs de Consulta NIF'),
'type': 'ir.actions.act_window',
'res_model': 'nif.validation.log',
'view_mode': 'list,form',
'domain': [('partner_id', '=', self.id)],
'target': 'current',
}
# NOVO: Função para apagar o histórico de consultas deste cliente
def action_clear_nif_logs(self):
self.ensure_one()
if self.env.get('nif.validation.log'):
logs = self.env['nif.validation.log'].search([('partner_id', '=', self.id)])
logs.unlink() # Apaga os registos da base de dados
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': _('Histórico Apagado'),
'message': _('Todo o histórico de consultas deste NIF foi apagado.'),
'type': 'warning',
}
}
# 2. LÓGICA DE EXTRAÇÃO (API AGT)
@api.onchange('nif_ao')
def _onchange_nif_ao_fetch_agt(self):
if not self.nif_ao or len(self.nif_ao.strip()) < 9:
return
nif = self.nif_ao.strip()
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
url = f"https://portaldocontribuinte.minfin.gov.ao/consultar-nif-do-contribuinte?nif={nif}"
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0'}
try:
_logger.info(">>> A consultar AGT para NIF: %s", nif)
response = requests.get(url, headers=headers, timeout=15, verify=False)
if response.status_code == 200 and response.text:
html = response.text
clean_text = re.sub(r'<[^>]+>', ' ', html)
clean_text = re.sub(r'\s+', ' ', clean_text).strip()
nome_m = re.search(r'Nome:\s*(.*?)\s*Tipo:', clean_text, re.IGNORECASE)
tipo_m = re.search(r'Tipo:\s*(.*?)\s*Estado:', clean_text, re.IGNORECASE)
est_m = re.search(r'Estado:\s*(.*?)\s*Inadimplente:', clean_text, re.IGNORECASE)
inad_m = re.search(r'Inadimplente:\s*(.*?)\s*Regime de IVA:', clean_text, re.IGNORECASE)
iva_m = re.search(r'Regime de IVA:\s*(.*?)\s*Residente Fiscal', clean_text, re.IGNORECASE)
if nome_m:
self.name = nome_m.group(1).strip()
if tipo_m:
self.nif_ao_contributor_type = tipo_m.group(1).strip()
if est_m:
self.nif_ao_state = est_m.group(1).strip()
if inad_m:
self.nif_ao_inadimplente = inad_m.group(1).strip()
if iva_m:
self.nif_ao_regime_iva = iva_m.group(1).strip()
self.nif_ao_validated = True
self.nif_ao_last_validation = fields.Datetime.now()
except Exception as e:
_logger.error("Erro na busca: %s", str(e))
# 3. AÇÃO DO BOTÃO "CONSULTAR" (Agora regista os Logs a sério!)
def action_validate_nif(self):
self.ensure_one()
if not self.nif_ao:
raise UserError(_("Por favor, preencha o campo NIF Angola primeiro."))
# 1. Faz a pesquisa no portal da AGT
self._onchange_nif_ao_fetch_agt()
# 2. Se a pesquisa correu bem, cria o registo no Histórico (Log)
if self.nif_ao_validated:
if self.env.get('nif.validation.log'):
self.env['nif.validation.log'].create({
'partner_id': self.id,
'nif': self.nif_ao,
'state': 'Sucesso',
'raw_response': f"Nome: {self.name} | Estado: {self.nif_ao_state} | IVA: {self.nif_ao_regime_iva}"
})
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': _('Sucesso'),
'message': _('Dados da AGT consultados com sucesso e registados no histórico.'),
'type': 'success',
}
}
else:
raise UserError(_("Não foi possível aceder à AGT. Verifique o NIF."))