From da9ab3e892baab735f1baa7383ad2d24baf67ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 16 Apr 2025 11:19:58 -0300 Subject: [PATCH] =?UTF-8?q?Coloca=20a=20busca=20por=20semelhan=C3=A7a=20de?= =?UTF-8?q?=20nome=20como=20classmethod=20em=20Orgao?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/casas/models.py | 25 ++++++++++++++++++++++++- sigi/apps/convenios/models.py | 21 +++------------------ 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/sigi/apps/casas/models.py b/sigi/apps/casas/models.py index a8b33af..2701ca5 100644 --- a/sigi/apps/casas/models.py +++ b/sigi/apps/casas/models.py @@ -1,4 +1,5 @@ import random +from difflib import SequenceMatcher from string import ascii_uppercase from unicodedata import normalize from django.contrib.contenttypes.fields import GenericRelation @@ -9,7 +10,7 @@ from django.utils.translation import gettext as _ from sigi.apps.contatos.models import Municipio from sigi.apps.servidores.models import Servidor -from sigi.apps.utils import SearchField, mask_cnpj, valida_cnpj +from sigi.apps.utils import SearchField, mask_cnpj, valida_cnpj, to_ascii class TipoOrgao(models.Model): @@ -135,6 +136,28 @@ class Orgao(models.Model): brasao_largura = models.SmallIntegerField(editable=False, null=True) brasao_altura = models.SmallIntegerField(editable=False, null=True) + def _mathnames(nome, orgaos): + for o, nome_canonico in orgaos: + ratio = SequenceMatcher( + None, to_ascii(nome).lower(), nome_canonico + ).ratio() + if ratio > 0.9: + yield (o, ratio) + + @classmethod + def get_semelhantes(cls, nome, orgaos=None): + if orgaos is None: + orgaos = [ + (o, f"{to_ascii(o.nome)} - {o.uf_sigla}".lower()) + for o in Orgao.objects.all() + .order_by() + .annotate(uf_sigla=models.F("municipio__uf__sigla")) + ] + return sorted( + cls._mathnames(nome, orgaos), + key=lambda m: m[1], + ) + class Meta: ordering = ("nome",) verbose_name = _("órgão") diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index 5be3020..23ba55d 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -675,20 +675,6 @@ class Gescon(models.Model): importados/atualizados) """ - def mathnames(nome, orgaos, all=False): - for o, nome_canonico in orgaos: - ratio = SequenceMatcher( - None, to_ascii(nome).lower(), nome_canonico - ).ratio() - if ratio > 0.9: - yield (o, ratio) - - def get_semelhantes(nome, orgaos, all=False): - return sorted( - mathnames(nome, orgaos, all), - key=lambda m: m[1], - ) - self.ultima_importacao = "" if self.checksums is None: self.checksums = {} @@ -946,7 +932,7 @@ class Gescon(models.Model): # da prefeitura, e ambos terem convênio com o ILB. # Podemos tentar desambiguar pelo nome mais # semelhante. - orgao = get_semelhantes( + orgao = Orgao.get_semelhantes( to_ascii(contrato["nomeFornecedor"]).lower(), [ ( @@ -957,7 +943,6 @@ class Gescon(models.Model): .order_by() .annotate(uf_sigla=F("municipio__uf__sigla")) ], - all=True, )[0][0] except Orgao.DoesNotExist: # Encontrou 0: Vamos seguir sem órgao e tentar @@ -982,13 +967,13 @@ class Gescon(models.Model): erros += 1 continue # Tentar primeiro com o nome igual veio do GESCON - semelhantes = get_semelhantes( + semelhantes = Orgao.get_semelhantes( to_ascii(contrato["nomeFornecedor"]).lower(), todos_orgaos, ) if not semelhantes: # Não achou, então vamos tentar com o nome limpado - semelhantes = get_semelhantes( + semelhantes = Orgao.get_semelhantes( to_ascii(nome).lower(), todos_orgaos, )