from typing import Any
from django.db.models.query import QuerySet
from django.http import HttpRequest
from email_validator import validate_email, EmailNotValidError
from django.db.models import F
from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.translation import gettext as _
from django_weasyprint.views import WeasyTemplateResponse
from djbs import djbs_constants as djbsc
from import_export import resources
from import_export.admin import ExportActionMixin
from import_export.fields import Field
from sigi.apps.casas.forms import OrgaoForm, OcorrenciaInlineForm
from sigi.apps.casas.models import Orgao, Funcionario, TipoOrgao
from sigi.apps.casas.filters import (
GerentesInterlegisFilter,
ServicoFilter,
)
from sigi.apps.convenios.filters import (
TipoProjetoFilter,
ExcluirTipoProjetoFilter,
)
from sigi.apps.contatos.models import Telefone
from sigi.apps.convenios.models import Convenio
from sigi.apps.ocorrencias.models import Ocorrencia
from sigi.apps.parlamentares.models import Parlamentar
from sigi.apps.servicos.models import Servico
from sigi.apps.servicos.filters import ServicoAtivoFilter
from sigi.apps.servidores.models import Servidor
from sigi.apps.utils.mixins import AsciifyQParameter
from sigi.apps.utils.mixins import ReturnMixin
class OrgaoExportResourceContato(resources.ModelResource):
class Meta:
model = Orgao
fields = ("nome", "email")
export_order = fields
name = "Exportação para aplicativo Contatos"
def dehydrate_nome(self, orgao):
return orgao.nome[:50]
def export(self, queryset=None, *args, **kwargs):
if queryset is not None:
queryset = queryset.exclude(email="").filter(
email__regex=r"([A-Za-z0-9]+[.\-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+"
)
return super().export(queryset, *args, **kwargs)
class OrgaoExportResourseGeral(resources.ModelResource):
presidente = Field(column_name="presidente")
telefone = Field(column_name="telefone")
# servicos_seit = Field(column_name='servicos_seit')
contato = Field(column_name="contato")
nome = Field(column_name="nome")
class Meta:
model = Orgao
fields = (
"municipio__codigo_ibge",
"cnpj",
"municipio__codigo_tse",
"nome",
"municipio__nome",
"municipio__uf__sigla",
"presidente",
"logradouro",
"bairro",
"cep",
"telefone",
"pagina_web",
"email",
"ult_alt_endereco",
"contato",
)
export_order = fields
name = "Exportação de uso geral"
def dehydrate_nome(self, orgao):
return orgao.nome[:50]
def dehydrate_presidente(self, orgao):
return orgao.presidente
def dehydrate_telefone(self, orgao):
return orgao.telefone
# def dehydrate_servicos_seit(self, orgao):
# servicos = [s.tipo_servico.nome for s in orgao.servico_set.filter(
# data_desativacao__isnull=True)]
# return ", ".join(servicos)
def dehydrate_contato(self, orgao):
return ", ".join(
[
f"{c.cargo if c.cargo else 'Sem cargo'}: {c.nome} ({c.email})"
for c in orgao.funcionario_set.filter(desativado=False)
]
)
class TelefonesInline(GenericTabularInline):
model = Telefone
readonly_fields = ("ult_alteracao",)
extra = 1
class ParlamentarInline(admin.TabularInline):
model = Parlamentar
fields = (
"get_foto",
"nome_parlamentar",
"status_mandato",
"get_partido",
"email",
"redes_sociais",
"presidente",
)
readonly_fields = fields
extra = 0
max_num = 0
show_change_link = True
can_delete = False
@mark_safe
@admin.display(description=_("Foto"))
def get_foto(self, obj):
if obj.foto:
return f''
else:
return (
'account_circle'
)
@admin.display(description=_("Partido"))
def get_partido(self, obj):
return obj.partido.sigla
class FuncionarioInline(admin.StackedInline):
model = Funcionario
stacked_cols = "1"
fields = (
("desativado", "ult_alteracao"),
"setor",
"nome",
("cpf", "identidade", "sexo"),
("nota", "email"),
("cargo", "funcao"),
("redes_sociais", "observacoes"),
)
readonly_fields = ["ult_alteracao"]
extra = 0
show_change_link = True
can_delete = False
verbose_name_plural = _("Contatos da Casa")
ordering = ["setor", "-ult_alteracao"]
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.exclude(desativado=True)
class ListaFuncionarioInline(admin.TabularInline):
model = Funcionario
fields = (
"get_setor",
"nome",
"nota",
"get_email_link",
"observacoes",
"ult_alteracao",
)
readonly_fields = fields
extra = 0
max_num = 0
show_change_link = True
can_delete = False
verbose_name_plural = _("Lista de contatos")
ordering = ["setor", "-ult_alteracao"]
djbs_hide_original = True
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.exclude(desativado=True)
def has_change_permission(self, request, obj):
return False
@admin.display(description=_("setor"))
def get_setor(self, func):
if func.setor == "contato_interlegis":
return format_html(
"{setor}",
setor=func.get_setor_display(),
)
return func.get_setor_display()
@admin.display(description=_("e-mail"))
def get_email_link(self, func):
return format_html(
"{email}",
email=func.email,
)
class ConveniosInline(admin.TabularInline):
model = Convenio
fields = (
"num_processo_sf",
"link_sigad",
"status_convenio",
"num_convenio",
"get_projeto",
"data_retorno_assinatura",
"data_termino_vigencia",
"data_pub_diario",
"data_sigad",
"data_solicitacao",
)
readonly_fields = fields
ordering = ("-data_retorno_assinatura",)
readonly_fields = fields
extra = 0
max_num = 0
show_change_link = True
can_delete = False
def get_queryset(self, request: HttpRequest):
return (
super()
.get_queryset(request)
.order_by(
F("data_retorno_assinatura").desc(nulls_last=True),
F("data_termino_vigencia").desc(nulls_last=True),
)
)
@mark_safe
@admin.display(description=_("Status do convênio"))
def status_convenio(self, obj):
if obj.pk is None:
return None
status = obj.get_status()
if status in ["Vencido", "Desistência", "Cancelado", "Extinto"]:
label = r"bg-danger"
elif status == "Vigente":
label = r"bg-success"
elif status == "Pendente":
label = r"bg-alert"
else:
label = r""
return f'{status}'
@admin.display(description=_("Ver no SIGAD"))
def link_sigad(self, obj):
if obj.pk is None:
return ""
return mark_safe(obj.get_sigad_url(display_type="icone"))
@admin.display(description=_("Tipo de convênio"))
def get_projeto(self, obj):
if obj.pk is None:
return ""
return obj.projeto.sigla
class ServicoInline(admin.TabularInline):
model = Servico
fields = (
"get_tipo_servico",
"get_url",
"hospedagem_interlegis",
"data_ativacao",
"data_desativacao",
"resultado_verificacao",
"data_ultimo_uso",
)
readonly_fields = fields
ordering = ("-data_desativacao", "-data_ativacao", "tipo_servico")
extra = 0
max_num = 0
show_change_link = True
can_delete = False
@admin.display(description=_("Tipo de serviço"), ordering="tipo_servico")
def get_tipo_servico(self, obj):
return obj.tipo_servico.sigla
@mark_safe
@admin.display(description="Url do serviço", ordering="url")
def get_url(self, obj):
return f"{obj.url}"
class OcorrenciaInline(admin.StackedInline):
model = Ocorrencia
form = OcorrenciaInlineForm
stacked_cols = 1
fields = (
("data_criacao", "data_modificacao"),
("categoria", "tipo_contato"),
"assunto",
("prioridade", "status", "ticket"),
("descricao", "resolucao"),
"servidor_registro",
("anexo", "descricao_anexo"),
"get_anexos",
)
autocomplete_fields = ("categoria", "tipo_contato")
readonly_fields = [
"data_criacao",
"data_modificacao",
"servidor_registro",
"get_anexos",
]
ordering = ("-data_modificacao",)
extra = 0
show_change_link = True
can_delete = False
def has_add_permission(self, request, obj):
if Servidor.objects.filter(user=request.user).exists():
return super().has_add_permission(request, obj)
return False
def has_change_permission(self, request, obj):
if Servidor.objects.filter(user=request.user).exists():
return super().has_change_permission(request, obj)
return False
@admin.display(description=_("Anexos"))
@mark_safe
def get_anexos(self, obj):
anexos = [
f"