Repository: interlegis/sapl

Issue:
Separar cadastro de Parlamentar de vinculação a Legislatura
Atualmente, o cadastro de parlamentares é feito mediante a seleção da legislatura e posterior clique no botão Adicionar Parlamentar. Esse tipo de operação induz ao erro pois o operador acaba por cadastrar o parlamentar mais de uma vez, uma para cada legislatura.

## Comportamento Esperado
Evitar a duplicidade de parlamentares cadastrados no SAPL. O cadastro deve ser único com vários mandatos.

## Comportamento Atual
O sistema permite que um mesmo parlamentar seja cadastrado múltiplas vezes no sistema, gerando inconsistência de dados.

## Possível Solução
A função do botão de 'Adicionar Parlamentar' é vincular um Parlamentar previamente cadastrado a uma Legislatura. A ideia é que a tela de cadastro do parlamentar seja movida para Tabelas Auxiliares (sendo chamada de Cadastrar Parlamentar) e uma nova tela (com form) que vincule parlamentares cadastrados a suas legislaturas através da criação de um mandato no botão Adicionar Parlamentar.

## Passos para Reproduzir (para bugs)
1. 
2.
3.
4.

## Contexto
<!--- Como esse problema o afeta? O que você está tentando realizar? -->
<!--- Fornecer o contexto nos ajuda a encontrar uma solução que seja mais útil no mundo real -->

## Imagens do Ocorrido
<!--- Representação visual em vídeo ou imagem do ocorrido -->
<!--- Se está descrevendo um bug poste imagens ou vídeos na repordução do bug citado, caso se aplique -->

## Seu Ambiente
<!--- Inclua detalhes relevantes sobre o ambiente em que você presenciou/experienciou o bug. -->
* Versão usada (_Release_):
* Nome e versão do navegador:
* Nome e versão do Sistema Operacional (desktop ou mobile):
* Link para o seu projeto (Caso de fork deste projeto):



Discussion:
Maravilha!!! 
Isso nos remete a uma separação:
- da tela administrativa do usuário que não precisa haver seleção legislatura para dar manutenção
- da tela anônima que pode inclusive concentrar mesa diretora e parlamento numa interface só. vide: https://www.jatai.go.leg.br/parlamentar

Resolving patch:
diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py
--- a/sapl/parlamentares/forms.py
+++ b/sapl/parlamentares/forms.py
@@ -506,3 +506,65 @@ def save(self, commit=False):
         votante.user = u
         votante.save()
         return votante
+
+
+class VincularParlamentarForm(forms.Form):
+    logger = logging.getLogger(__name__)
+
+    parlamentar = forms.ModelChoiceField(
+        label=Parlamentar._meta.verbose_name,
+        queryset=Parlamentar.objects.filter(ativo=True),
+        required=True,
+        empty_label='Selecione'
+    )
+
+    legislatura = forms.ModelChoiceField(
+        label=Legislatura._meta.verbose_name,
+        queryset=Legislatura.objects.all(),
+        required=True,
+        empty_label='Selecione'
+    )
+
+    data_expedicao_diploma = forms.DateField(
+        label='Data de Expedição do Diploma',
+        required=False,
+        widget=forms.DateInput(format='%d/%m/%Y')
+    )
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        row1 = to_row([
+            ('parlamentar', 6),
+            ('legislatura', 3),
+            ('data_expedicao_diploma', 3)
+        ])
+
+        self.helper = SaplFormHelper()
+        self.helper.layout = Layout(
+            Fieldset(
+                'Vincular Parlamentar',
+                row1,
+                form_actions(label='Vincular')
+            )
+        )
+
+    def clean(self):
+        super().clean()
+
+        if not self.is_valid():
+            return self.cleaned_data
+
+        cleaned_data = self.cleaned_data
+        parlamentar = cleaned_data['parlamentar']
+        legislatura = cleaned_data['legislatura']
+        data_expedicao_diploma = cleaned_data['data_expedicao_diploma']
+
+        if parlamentar.mandato_set.filter(legislatura=legislatura):
+            self.logger.error('Parlamentar já está vinculado a legislatura informada.')
+            raise ValidationError(_('Parlamentar já está vinculado a legislatura informada.'))
+        elif data_expedicao_diploma and legislatura.data_inicio <= data_expedicao_diploma:
+            self.logger.error('Data da Expedição do Diploma deve ser anterior a data de início da Legislatura.')
+            raise ValidationError(_('Data da Expedição do Diploma deve ser anterior a data de início da Legislatura.'))
+
+        return cleaned_data
diff --git a/sapl/parlamentares/urls.py b/sapl/parlamentares/urls.py
--- a/sapl/parlamentares/urls.py
+++ b/sapl/parlamentares/urls.py
@@ -20,7 +20,7 @@
                                       remove_parlamentar_composicao,
                                       lista_parlamentares,
                                       parlamentares_filiados,
-                                      PesquisarParlamentarView)
+                                      PesquisarParlamentarView, VincularParlamentarView)
 
 from .apps import AppConfig
 
@@ -44,6 +44,9 @@
     url(r'^parlamentar/(?P<pk>\d+)/materias$',
         ParlamentarMateriasView.as_view(), name='parlamentar_materias'),
 
+    url(r'^parlamentar/vincular-parlamentar/$',
+        VincularParlamentarView.as_view(), name='vincular_parlamentar'),
+
     url(r'^sistema/coligacao/',
         include(ColigacaoCrud.get_urls() +
                 ComposicaoColigacaoCrud.get_urls())),
diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py
--- a/sapl/parlamentares/views.py
+++ b/sapl/parlamentares/views.py
@@ -3,6 +3,7 @@
 import logging
 
 from django.contrib import messages
+from django.contrib.auth.mixins import PermissionRequiredMixin
 from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
 from django.core.urlresolvers import reverse, reverse_lazy
@@ -33,7 +34,7 @@
 from sapl.utils import (parlamentares_ativos, show_results_filter_set)
 
 from .forms import (FiliacaoForm, FrenteForm, LegislaturaForm, MandatoForm,
-                    ParlamentarCreateForm, ParlamentarForm, VotanteForm, ParlamentarFilterSet)
+                    ParlamentarCreateForm, ParlamentarForm, VotanteForm, ParlamentarFilterSet, VincularParlamentarForm)
 from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa,
                      Dependente, Filiacao, Frente, Legislatura, Mandato,
                      NivelInstrucao, Parlamentar, Partido, SessaoLegislativa,
@@ -1138,3 +1139,30 @@ def altera_field_mesa_public_view(request):
          'lista_fotos': lista_fotos,
          'sessao_selecionada': sessao_selecionada,
          'msg': ('', 1)})
+
+
+class VincularParlamentarView(PermissionRequiredMixin, FormView):
+    logger = logging.getLogger(__name__)
+    form_class = VincularParlamentarForm
+    template_name = 'parlamentares/vincular_parlamentar.html'
+    permission_required = ('parlamentares.add_parlamentar', )
+
+    def get_success_url(self):
+        return reverse('sapl.parlamentares:parlamentar_list')
+
+    def form_valid(self, form):
+        kwargs = {
+            'parlamentar': form.cleaned_data['parlamentar'],
+            'legislatura': form.cleaned_data['legislatura'],
+            'data_inicio_mandato': form.cleaned_data['legislatura'].data_inicio,
+            'data_fim_mandato': form.cleaned_data['legislatura'].data_fim
+        }
+
+        data_expedicao_diploma = form.cleaned_data.get('data_expedicao_diploma')
+        if data_expedicao_diploma:
+            kwargs.update({'data_expedicao_diploma': data_expedicao_diploma})
+
+        mandato = Mandato.objects.create(**kwargs)
+        mandato.save()
+
+        return HttpResponseRedirect(self.get_success_url())


Test patch: