Repository: interlegis/sapl

Issue:
Bug parlamentar duplicado
Temos um caso onde o suplente de vereador assumiu por várias vezes e por diversos motivos na mesma legislatura. Registramos essas entradas e saídas criando mandato cada vez q tal suplente assumia. Essa semana um vereador perdeu o mandato e agora esse suplente assume definitivamente. Criamos um novo mandato e informamos que o mesmo nesse momento que assume se torna o vereador titular. Contudo, na lista de presença (figura 1) - tanto da sessão plenária quanto da votação das matérias - aparece o nome do parlamentar tantas quantas foram as substituições nos mandatos, mesmo que tenhamos finalizado os mandatos anteriores e esteja em aberto somente o último. Da mesma forma na lista dos parlamentares aparece duplicado o parlamentar (figura 2). 
![Figura2](https://user-images.githubusercontent.com/57186085/67890144-eaed5300-fb2e-11e9-9d7c-cdc788921ca8.jpeg)
![Figura1](https://user-images.githubusercontent.com/57186085/67890145-eaed5300-fb2e-11e9-90a5-ff87f3c46eea.jpeg)




Discussion:

Resolving patch:
diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py
--- a/sapl/parlamentares/views.py
+++ b/sapl/parlamentares/views.py
@@ -514,8 +514,7 @@ class BaseMixin(Crud.BaseMixin):
         list_field_names = [
             'nome_parlamentar',
             'filiacao_atual',
-            'ativo',
-            'mandato_titular']
+            'ativo']
 
     class DetailView(Crud.DetailView):
 
@@ -591,8 +590,7 @@ def get_queryset(self):
             username = self.request.user.username
             if legislatura_id >= 0:
                 return queryset.filter(
-                    mandato__legislatura_id=legislatura_id).annotate(
-                        mandato_titular=F('mandato__titular')).distinct()
+                    mandato__legislatura_id=legislatura_id).distinct()
             else:
                 try:
                     self.logger.debug(
@@ -608,8 +606,7 @@ def get_queryset(self):
                                      ". Objeto encontrado com sucesso.")
                     if l is None:
                         return Legislatura.objects.all()
-                    return queryset.filter(mandato__legislatura_id=l).annotate(
-                        mandato_titular=F('mandato__titular'))
+                    return queryset.filter(mandato__legislatura_id=l)
 
         def get_headers(self):
             return [_('Parlamentar'), _('Partido'),
@@ -624,19 +621,38 @@ def get_context_data(self, **kwargs):
             context['legislaturas'] = legislaturas
             context['legislatura_id'] = self.take_legislatura_id()
 
+            # Pega a Legislatura
+            legislatura = Legislatura.objects.get(
+                id=context['legislatura_id'])
+
             for row in context['rows']:
 
                 # Pega o Parlamentar por meio da pk
                 parlamentar = Parlamentar.objects.get(
                     id=(row[0][1].split('/')[-1]))
 
+                # Conserta a issue do github https://github.com/interlegis/sapl/issues/3028
+                # Inicialmente a titularidade era conseguida através do código
+                # queryset.filter(mandato__legislatura_id=legislatura_id).annotate(
+                #                 mandato_titular=F('mandato__titular')).distinct()
+                # em get_queryset(), MAS não funciona se o parlamentar tem vários
+                # mandatos na mesma legislatura, sendo ao menos um titular e outro não,
+                # pois isso gera entradas repetidas. Este código corrige essa situação.
+                mandato = Mandato.objects.filter(
+                    parlamentar=parlamentar,
+                    data_inicio_mandato__gte=legislatura.data_inicio,
+                    data_fim_mandato__lte=legislatura.data_fim
+                ).order_by('-data_inicio_mandato').first()
+
+                if mandato:
+                    titular = 'Sim' if mandato.titular else 'Não'
+                    row.append((titular, None))
+                else:
+                    row.append(('-', None))
+
                 for index, value in enumerate(row):
                     row[index] += (None if index else parlamentar,)
 
-                # Pega a Legislatura
-                legislatura = Legislatura.objects.get(
-                    id=context['legislatura_id'])
-
                 # Coloca a filiação atual ao invés da última
                 # As condições para mostrar a filiação são:
                 # A data de filiacao deve ser menor que a data de fim
diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py
--- a/sapl/sessao/views.py
+++ b/sapl/sessao/views.py
@@ -501,18 +501,16 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
 
 
 def get_presencas_generic(model, sessao, legislatura):
-    presencas = model.objects.filter(
-        sessao_plenaria=sessao)
+    presentes = [p.parlamentar for p in model.objects.filter(sessao_plenaria=sessao)]
 
-    presentes = [p.parlamentar for p in presencas]
+    parlamentares_mandato = Mandato.objects.filter(
+                              legislatura=legislatura,
+                              data_inicio_mandato__lte=sessao.data_inicio,
+                              data_fim_mandato__gte=sessao.data_inicio
+    ).distinct().order_by(
+        'parlamentar__nome_parlamentar')
 
-    presentes = sorted(
-        presentes, key=lambda x: remover_acentos(x.nome_parlamentar))
-
-    mandato = Mandato.objects.filter(
-        legislatura=legislatura).order_by('parlamentar__nome_parlamentar')
-
-    for m in mandato:
+    for m in parlamentares_mandato:
         if m.parlamentar in presentes:
             yield (m.parlamentar, True)
         else:
@@ -1629,11 +1627,11 @@ def get_presenca_sessao(sessao_plenaria):
 
     parlamentares_sessao = [p.parlamentar for p in SessaoPlenariaPresenca.objects.filter(
         sessao_plenaria_id=sessao_plenaria.id
-    ).order_by('parlamentar__nome_parlamentar')]
+    ).order_by('parlamentar__nome_parlamentar').distinct()]
 
     ausentes_sessao = JustificativaAusencia.objects.filter(
         sessao_plenaria_id=sessao_plenaria.id
-    ).order_by('parlamentar__nome_parlamentar')
+    ).distinct().order_by('parlamentar__nome_parlamentar')
 
     return ({'presenca_sessao': parlamentares_sessao,
              'justificativa_ausencia': ausentes_sessao})
@@ -1727,7 +1725,7 @@ def get_oradores_expediente(sessao_plenaria):
 def get_presenca_ordem_do_dia(sessao_plenaria):
     parlamentares_ordem = [p.parlamentar for p in PresencaOrdemDia.objects.filter(
         sessao_plenaria_id=sessao_plenaria.id
-    ).order_by('parlamentar__nome_parlamentar')]
+    ).distinct().order_by('parlamentar__nome_parlamentar')]
 
     return {'presenca_ordem': parlamentares_ordem}
 


Test patch: