From 4c843421ec71c6245e3c07cdb8d02b00d124c5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20=C3=81lvarez?= Date: Thu, 2 Aug 2018 12:17:03 -0300 Subject: [PATCH] login de candidatos al reves --- merepresenta/candidates_backend/urls.py | 10 -- merepresenta/candidates_backend/views.py | 0 .../__init__.py | 0 merepresenta/candidatos/forms.py | 27 +++ merepresenta/candidatos/strategy.py | 23 +++ merepresenta/candidatos/urls.py | 25 +++ merepresenta/candidatos/views.py | 80 +++++++++ merepresenta/fixtures/merep_mini.yaml | 12 +- .../migrations/0014_auto_20180801_1551.py | 20 +++ merepresenta/models.py | 2 +- merepresenta/templates/base.html | 4 + .../templates/candidatos/cpf_and_ddn.html | 36 ++++ merepresenta/templates/candidatos/login.html | 13 ++ .../templates/merepresenta/index.html | 10 +- .../login_and_first_page_view_tests.py | 73 -------- .../__init__.py | 0 .../login_and_first_page_view_tests.py | 163 ++++++++++++++++++ merepresenta/tests/model_tests.py | 10 +- merepresenta/tse_processor.py | 33 ++-- merepresenta/urls.py | 2 +- 20 files changed, 435 insertions(+), 108 deletions(-) delete mode 100644 merepresenta/candidates_backend/urls.py delete mode 100644 merepresenta/candidates_backend/views.py rename merepresenta/{candidates_backend => candidatos}/__init__.py (100%) create mode 100644 merepresenta/candidatos/forms.py create mode 100644 merepresenta/candidatos/strategy.py create mode 100644 merepresenta/candidatos/urls.py create mode 100644 merepresenta/candidatos/views.py create mode 100644 merepresenta/migrations/0014_auto_20180801_1551.py create mode 100644 merepresenta/templates/candidatos/cpf_and_ddn.html create mode 100644 merepresenta/templates/candidatos/login.html delete mode 100644 merepresenta/tests/candidates_backend/login_and_first_page_view_tests.py rename merepresenta/tests/{candidates_backend => candidatos}/__init__.py (100%) create mode 100644 merepresenta/tests/candidatos/login_and_first_page_view_tests.py diff --git a/merepresenta/candidates_backend/urls.py b/merepresenta/candidates_backend/urls.py deleted file mode 100644 index 9773a2c6..00000000 --- a/merepresenta/candidates_backend/urls.py +++ /dev/null @@ -1,10 +0,0 @@ - -from django.conf.urls import url, include -from django.views.generic.base import TemplateView - - -urlpatterns = [ - url(r'^$', - TemplateView.as_view(template_name="merepresenta/index.html"), - name='candidate_cpf'), -] diff --git a/merepresenta/candidates_backend/views.py b/merepresenta/candidates_backend/views.py deleted file mode 100644 index e69de29b..00000000 diff --git a/merepresenta/candidates_backend/__init__.py b/merepresenta/candidatos/__init__.py similarity index 100% rename from merepresenta/candidates_backend/__init__.py rename to merepresenta/candidatos/__init__.py diff --git a/merepresenta/candidatos/forms.py b/merepresenta/candidatos/forms.py new file mode 100644 index 00000000..1bd30548 --- /dev/null +++ b/merepresenta/candidatos/forms.py @@ -0,0 +1,27 @@ +# coding=utf-8 +from django import forms +from backend_candidate.models import Candidacy +from merepresenta.models import Candidate + + +class CPFAndDdnForm(forms.Form): + cpf = forms.CharField(required=True) + nascimento = forms.DateField(required=True, input_formats=['%d/%m/%Y','%d/%m/%y', '%d-%m-%Y', '%d-%m-%y',]) + + def __init__(self, *args, **kwargs): + self.user = kwargs.pop('user') + super(CPFAndDdnForm, self).__init__(*args, **kwargs) + + def clean(self): + cpf = self.cleaned_data['cpf'] + ddn = self.cleaned_data.get('nascimento', None) + if ddn is None: + raise forms.ValidationError(u'Não encontramos o candidato') + try: + self.candidate = Candidate.objects.get(cpf=cpf, data_de_nascimento=ddn) + except Candidate.DoesNotExist: + raise forms.ValidationError(u'Não encontramos o candidato') + return self.cleaned_data + + def save(self): + return Candidacy.objects.create(user=self.user, candidate=self.candidate) \ No newline at end of file diff --git a/merepresenta/candidatos/strategy.py b/merepresenta/candidatos/strategy.py new file mode 100644 index 00000000..65753913 --- /dev/null +++ b/merepresenta/candidatos/strategy.py @@ -0,0 +1,23 @@ +from social_django.strategy import DjangoStrategy +from django.shortcuts import resolve_url +from django.contrib.auth import authenticate + + +class CandidateStrategy(DjangoStrategy): + + def get_setting(self, name): + if name in ['NEW_USER_REDIRECT_URL', 'LOGIN_REDIRECT_URL', 'SOCIAL_AUTH_FACEBOOK_LOGIN_REDIRECT_URL']: + return resolve_url('cpf_and_date') + return super(CandidateStrategy, self).get_setting(name) + + def create_user(self, *args, **kwargs): + user = super(CandidateStrategy, self).create_user(*args, **kwargs) + return user + + def authenticate(self, backend, *args, **kwargs): + kwargs['strategy'] = self + kwargs['storage'] = self.storage + kwargs['backend'] = backend + if 'request' in kwargs: + kwargs.pop('request') + return authenticate(*args, **kwargs) \ No newline at end of file diff --git a/merepresenta/candidatos/urls.py b/merepresenta/candidatos/urls.py new file mode 100644 index 00000000..69f0a404 --- /dev/null +++ b/merepresenta/candidatos/urls.py @@ -0,0 +1,25 @@ + +from django.conf.urls import url, include +from .views import (LoginView, + CPFAndDDNSelectView, + complete, + auth + ) + + +urlpatterns = [ + url(r'^login/?$', + LoginView.as_view(), + name='candidate_login'), + + url(r'^cpf_e_ddn/?$', + CPFAndDDNSelectView.as_view(), + name='cpf_and_date'), + url(r'^complete/(?P[^/]+)$', + complete, + name='candidate_social_complete' + ), + url(r'^login/(?P[^/]+)/?$', auth, + name='candidato_social_begin'), + +] diff --git a/merepresenta/candidatos/views.py b/merepresenta/candidatos/views.py new file mode 100644 index 00000000..8d781ecb --- /dev/null +++ b/merepresenta/candidatos/views.py @@ -0,0 +1,80 @@ +from django.views.generic.edit import FormView +from django.contrib.auth.mixins import LoginRequiredMixin +from django.core.urlresolvers import reverse_lazy +from django.http import HttpResponseNotFound, HttpResponseRedirect +from backend_candidate.models import Candidacy +from .forms import CPFAndDdnForm +from social_core.actions import do_complete, do_auth +from social_django.views import _do_login +from django.views.decorators.cache import never_cache +from django.views.decorators.csrf import csrf_exempt +from social_django.utils import psa, STORAGE, get_strategy +from django.views.generic.base import TemplateView +from backend_candidate.models import is_candidate + + + +class LoginView(TemplateView): + template_name="candidatos/login.html" + + def dispatch(self, *args, **kwargs): + if self.request.user.is_authenticated: + url = reverse_lazy('cpf_and_date') + return HttpResponseRedirect(url) + return super(LoginView, self).dispatch(*args, **kwargs) + + +class CPFAndDDNSelectView(LoginRequiredMixin, FormView): + form_class = CPFAndDdnForm + template_name = 'candidatos/cpf_and_ddn.html' + # login_url = reverse_lazy('') + def dispatch(self, *args, **kwargs): + if not self.request.user.is_authenticated: + return HttpResponseRedirect(reverse_lazy('index')) + if self.request.user.is_staff: + return HttpResponseNotFound() + try: + c = Candidacy.objects.get(user=self.request.user) + election = c.candidate.election + candidate = c.candidate + url = reverse_lazy('backend_candidate:complete_profile', kwargs={'slug': election.slug, 'candidate_slug': candidate.slug}) + return HttpResponseRedirect(url) + except Candidacy.DoesNotExist: + pass + + return super(CPFAndDDNSelectView, self).dispatch(*args, **kwargs) + + def get_form_kwargs(self): + original = super(CPFAndDDNSelectView, self).get_form_kwargs() + original['user'] = self.request.user + return original + + def form_valid(self, form): + form.save() + return super(CPFAndDDNSelectView, self).form_valid(form) + + + def get_success_url(self): + c = Candidacy.objects.get(user=self.request.user) + election = c.candidate.election + candidate = c.candidate + url = reverse_lazy('backend_candidate:complete_profile', kwargs={'slug': election.slug, 'candidate_slug': candidate.slug}) + return url + + + +def load_strategy(request=None): + return get_strategy('merepresenta.candidatos.strategy.CandidateStrategy', STORAGE, request) + +@never_cache +@csrf_exempt +@psa(load_strategy=load_strategy, redirect_uri='candidate_social_complete') +def complete(request, backend, *args, **kwargs): + return do_complete(request.backend, _do_login, request.user, + redirect_value='next', request=request, + *args, **kwargs) + +@never_cache +@psa('candidate_social_complete') +def auth(request, backend): + return do_auth(request.backend) \ No newline at end of file diff --git a/merepresenta/fixtures/merep_mini.yaml b/merepresenta/fixtures/merep_mini.yaml index 41448328..2a0bcf7d 100644 --- a/merepresenta/fixtures/merep_mini.yaml +++ b/merepresenta/fixtures/merep_mini.yaml @@ -187,37 +187,37 @@ - fields: {person_ptr: 1, name: Manuel Rojas, elections: [2], extra_info: {}} model: elections.candidate pk: 1 -- fields: {candidate_ptr: '1'} +- fields: {candidate_ptr: '1', cpf: '1'} model: merepresenta.candidate pk: 1 - fields: {person_ptr: 2, name: Alejandro Guillier, elections: [2], extra_info: {}} model: elections.candidate pk: 2 -- fields: {candidate_ptr: '2'} +- fields: {candidate_ptr: '2', cpf: '2'} model: merepresenta.candidate pk: 2 - fields: {person_ptr: 3, name: Pedro Araya, elections: [2], extra_info: {}} model: elections.candidate pk: 3 -- fields: {candidate_ptr: '3'} +- fields: {candidate_ptr: '3', cpf: '3'} model: merepresenta.candidate pk: 3 - fields: {person_ptr: 4, name: Gisela Contreras, elections: [1], extra_info: {}} model: elections.candidate pk: 4 -- fields: {candidate_ptr: '4'} +- fields: {candidate_ptr: '4', cpf: '4'} model: merepresenta.candidate pk: 4 - fields: {person_ptr: 5, name: Carlos Cantero, elections: [1], extra_info: {}} model: elections.candidate pk: 5 -- fields: {candidate_ptr: '5'} +- fields: {candidate_ptr: '5', cpf: '5'} model: merepresenta.candidate pk: 5 - fields: {person_ptr: 6, name: Daniel Guevara, elections: [1], extra_info: {}} model: elections.candidate pk: 6 -- fields: {candidate_ptr: '6'} +- fields: {candidate_ptr: '6', cpf: '6'} model: merepresenta.candidate pk: 6 - fields: {topic: 4, position: 8, person: 1} diff --git a/merepresenta/migrations/0014_auto_20180801_1551.py b/merepresenta/migrations/0014_auto_20180801_1551.py new file mode 100644 index 00000000..e31b94a3 --- /dev/null +++ b/merepresenta/migrations/0014_auto_20180801_1551.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.9 on 2018-08-01 15:51 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('merepresenta', '0013_candidate_data_de_nascimento'), + ] + + operations = [ + migrations.AlterField( + model_name='candidate', + name='cpf', + field=models.CharField(max_length=1024, unique=True), + ), + ] diff --git a/merepresenta/models.py b/merepresenta/models.py index e584a2d0..416e6e90 100644 --- a/merepresenta/models.py +++ b/merepresenta/models.py @@ -60,7 +60,7 @@ def get_queryset(self): class Candidate(OriginalCandidate): - cpf = models.CharField(max_length=1024, null=True) + cpf = models.CharField(max_length=1024, unique=True) nome_completo = models.CharField(max_length=1024, null=True) numero = models.CharField(max_length=1024, null=True) race = models.CharField(max_length=1024, null=True) diff --git a/merepresenta/templates/base.html b/merepresenta/templates/base.html index c66c0e84..a68bff6c 100644 --- a/merepresenta/templates/base.html +++ b/merepresenta/templates/base.html @@ -19,10 +19,13 @@ + + + {% block extra_head %} {% endblock extra_head %} @@ -56,6 +59,7 @@ + {% block scripts %} {% endblock scripts %} +{% endblock content %} \ No newline at end of file diff --git a/merepresenta/templates/candidatos/login.html b/merepresenta/templates/candidatos/login.html new file mode 100644 index 00000000..bdfaa41a --- /dev/null +++ b/merepresenta/templates/candidatos/login.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} +{% load staticfiles %} +{% load i18n %} + +{% block title %}- Portada{% endblock title %} + +{% block content %} + +{% endblock content %} \ No newline at end of file diff --git a/merepresenta/templates/merepresenta/index.html b/merepresenta/templates/merepresenta/index.html index c4978aba..a7340356 100644 --- a/merepresenta/templates/merepresenta/index.html +++ b/merepresenta/templates/merepresenta/index.html @@ -12,13 +12,19 @@

Ajude seus eleitores diff --git a/merepresenta/tests/candidates_backend/login_and_first_page_view_tests.py b/merepresenta/tests/candidates_backend/login_and_first_page_view_tests.py deleted file mode 100644 index 55d35df5..00000000 --- a/merepresenta/tests/candidates_backend/login_and_first_page_view_tests.py +++ /dev/null @@ -1,73 +0,0 @@ -# coding=utf-8 -from django.test import TestCase, override_settings -from merepresenta.models import Candidate, NON_WHITE_KEY, NON_MALE_KEY -from merepresenta.tests.volunteers import VolunteersTestCaseBase -from backend_candidate.models import CandidacyContact -from elections.models import PersonalData, Area -from django.core.urlresolvers import reverse -from django.contrib.auth.models import User -from social_django.models import UserSocialAuth -import mock -from django.views.generic.edit import FormView -from django.core import mail -from merepresenta.models import VolunteerInCandidate, VolunteerGetsCandidateEmailLog, Candidate -from merepresenta.voluntarios.models import VolunteerProfile -from elections.models import Election, Area -from django.conf import settings -import datetime - -PASSWORD = 'candidato123' - -@override_settings(ROOT_URLCONF='merepresenta.stand_alone_urls') -class CandidateLoginView(VolunteersTestCaseBase): - def setUp(self): - super(CandidateLoginView, self).setUp() - session = self.client.session - session['facebook_state'] = '1' - session.save() - - # def test_get_login(self): - # url = reverse('candidate_login') - # response = self.client.get(url) - # self.assertEquals(response.status_code, 200) - - -@override_settings(ROOT_URLCONF='merepresenta.stand_alone_urls') -class CPFChoosingView(VolunteersTestCaseBase): - def setUp(self): - super(CPFChoosingView, self).setUp() - - - def test_ask_for_cpf_view(self): - url = reverse('candidate_cpf') - user = User.objects.create_user(username="candidato", password=PASSWORD) - self.client.login(username=user.username, password=PASSWORD) - response = self.client.get(url) - self.assertEquals(response.status_code, 200) - - # def test_post_to_the_view(self): - # d = datetime.datetime(2009, 10, 5, 18, 00) - # c = Candidate.objects.create(name='THE candidate', cpf='1234', ) - # data = { - - # } - # # self.assertTrue(response.context['form']) - - # @override_settings(SOCIAL_AUTH_FACEBOOK_KEY='1', - # SOCIAL_AUTH_FACEBOOK_SECRET='2') - # @mock.patch('social_core.backends.base.BaseAuth.request') - # def test_complete_with_facebook(self, mock_request): - # volunteer_index_url = reverse('volunteer_index') - # url = reverse('candidate_social_complete', kwargs={'backend': 'facebook'}) - # url += '?code=2&state=1' - # mock_request.return_value.json.return_value = {'access_token': '123'} - # with mock.patch('django.contrib.sessions.backends.base.SessionBase.set_expiry', side_effect=[OverflowError, None]): - # response = self.client.get(url) - - # self.assertEqual(response.status_code, 302) - # self.assertEqual(response.url, volunteer_index_url) - # social_user = UserSocialAuth.objects.get() - # created_user = social_user.user - # self.assertTrue(created_user.is_staff) - # self.assertTrue(created_user.volunteer_profile) - # self.assertIsNone(created_user.volunteer_profile.area) \ No newline at end of file diff --git a/merepresenta/tests/candidates_backend/__init__.py b/merepresenta/tests/candidatos/__init__.py similarity index 100% rename from merepresenta/tests/candidates_backend/__init__.py rename to merepresenta/tests/candidatos/__init__.py diff --git a/merepresenta/tests/candidatos/login_and_first_page_view_tests.py b/merepresenta/tests/candidatos/login_and_first_page_view_tests.py new file mode 100644 index 00000000..e8a08114 --- /dev/null +++ b/merepresenta/tests/candidatos/login_and_first_page_view_tests.py @@ -0,0 +1,163 @@ +# coding=utf-8 +from django.test import TestCase, override_settings +from merepresenta.models import Candidate, NON_WHITE_KEY, NON_MALE_KEY +from merepresenta.tests.volunteers import VolunteersTestCaseBase +from backend_candidate.models import CandidacyContact, Candidacy +from django.core.urlresolvers import reverse +from django.contrib.auth.models import User +from social_django.models import UserSocialAuth +import mock +from django.views.generic.edit import FormView +from django.core import mail +from merepresenta.models import VolunteerInCandidate, VolunteerGetsCandidateEmailLog, Candidate +from merepresenta.voluntarios.models import VolunteerProfile +from elections.models import PersonalData, Area, Election +from django.conf import settings +import datetime +from merepresenta.candidatos.forms import CPFAndDdnForm + +PASSWORD = 'candidato123' + +@override_settings(ROOT_URLCONF='merepresenta.stand_alone_urls') +class CandidateLoginView(VolunteersTestCaseBase): + def setUp(self): + super(CandidateLoginView, self).setUp() + session = self.client.session + session['facebook_state'] = '1' + session.save() + + def test_get_login(self): + url = reverse('candidate_login') + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + + def test_if_user_is_logged_in_but_not_candidate_and_not_volunteer_then_go_to_cpf(self): + url = reverse('candidate_login') + user = User.objects.create_user(username="candidate", password=PASSWORD) + self.client.login(username=user.username, password=PASSWORD) + response = self.client.get(url) + cpf_and_date_url = reverse('cpf_and_date') + self.assertRedirects(response, cpf_and_date_url) + + + @override_settings(SOCIAL_AUTH_FACEBOOK_KEY='1', + SOCIAL_AUTH_FACEBOOK_SECRET='2') + @mock.patch('social_core.backends.base.BaseAuth.request') + def test_complete_with_facebook(self, mock_request): + cpf_and_date_url = reverse('cpf_and_date') + url = reverse('candidate_social_complete', kwargs={'backend': 'facebook'}) + url += '?code=2&state=1' + mock_request.return_value.json.return_value = {'access_token': '123'} + with mock.patch('django.contrib.sessions.backends.base.SessionBase.set_expiry', side_effect=[OverflowError, None]): + response = self.client.get(url) + + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, cpf_and_date_url) + social_user = UserSocialAuth.objects.get() + created_user = social_user.user + self.assertFalse(created_user.is_staff) + + +@override_settings(ROOT_URLCONF='merepresenta.stand_alone_urls') +class CPFChoosingView(VolunteersTestCaseBase): + def setUp(self): + super(CPFChoosingView, self).setUp() + + def test_form_for_joining_a_user_and_a_candidate(self): + d = datetime.datetime(2009, 10, 5, 18, 00) + c = Candidate.objects.create(name='THE candidate', cpf='1234', data_de_nascimento=d) + user = User.objects.create(username='HolaSoyCandidato') + data = { + 'nascimento': d, + 'cpf': '1234', + } + form = CPFAndDdnForm(data=data, user=user) + self.assertTrue(form.is_valid()) + candidacy = form.save() + self.assertEquals(candidacy.candidate, c) + self.assertEquals(candidacy.user, user) + + def test_form_invalid(self): + d = datetime.datetime(2009, 10, 5, 18, 00) + c = Candidate.objects.create(name='THE candidate', cpf='1234', data_de_nascimento=d) + user = User.objects.create(username='HolaSoyCandidato') + data = { + 'nascimento': d, + 'cpf': '4321', + } + form = CPFAndDdnForm(data=data, user=user) + self.assertFalse(form.is_valid()) + + d = datetime.datetime(2019, 10, 5, 18, 00) + data = { + 'nascimento': d, + 'cpf': '1234', + } + form = CPFAndDdnForm(data=data, user=user) + self.assertFalse(form.is_valid()) + + def test_get_view(self): + url = reverse('cpf_and_date') + response = self.client.get(url) + self.assertEquals(response.status_code, 302) + volunteer = User.objects.create_user(username="voluntario", password=PASSWORD, is_staff=True) + possible_candidate = User.objects.create_user(username='EuSoCandidato', password=PASSWORD) + + self.client.login(username=volunteer.username, password=PASSWORD) + response = self.client.get(url) + self.assertEquals(response.status_code, 404) + + self.client.logout() + self.client.login(username=possible_candidate.username, password=PASSWORD) + response = self.client.get(url) + self.assertEquals(response.status_code, 200) + form = response.context['form'] + self.assertIsInstance(form, CPFAndDdnForm) + + # If user has another candidate connected then take it directly to the backend_candidate_home view + area = Area.objects.create(name="area") + election = Election.objects.create(name='ele', area=area) + candidate = Candidate.objects.create(name="Candi") + election.candidates.add(candidate) + Candidacy.objects.create(candidate=candidate, user=possible_candidate) + url_complete_profile = reverse('backend_candidate:complete_profile', kwargs={'slug': election.slug, 'candidate_slug': candidate.slug}) + response = self.client.get(url) + self.assertRedirects(response, url_complete_profile) + + + def test_post_to_the_view(self): + d = datetime.datetime(2009, 10, 5, 18, 00) + area = Area.objects.create(name="area") + election = Election.objects.create(name='ele', area=area) + c = Candidate.objects.create(name='THE candidate', cpf='1234', data_de_nascimento=d) + election.candidates.add(c) + data = { + 'nascimento': d.strftime('%d/%m/%Y'), + 'cpf': '1234', + } + url = reverse('cpf_and_date') + possible_candidate = User.objects.create_user(username='EuSoCandidato', password=PASSWORD) + self.client.login(username=possible_candidate.username, password=PASSWORD) + + response = self.client.post(url, data=data) + self.assertEquals(response.status_code, 302) + candidacy = Candidacy.objects.get(user=possible_candidate) + + # @override_settings(SOCIAL_AUTH_FACEBOOK_KEY='1', + # SOCIAL_AUTH_FACEBOOK_SECRET='2') + # @mock.patch('social_core.backends.base.BaseAuth.request') + # def test_complete_with_facebook(self, mock_request): + # volunteer_index_url = reverse('volunteer_index') + # url = reverse('candidate_social_complete', kwargs={'backend': 'facebook'}) + # url += '?code=2&state=1' + # mock_request.return_value.json.return_value = {'access_token': '123'} + # with mock.patch('django.contrib.sessions.backends.base.SessionBase.set_expiry', side_effect=[OverflowError, None]): + # response = self.client.get(url) + + # self.assertEqual(response.status_code, 302) + # self.assertEqual(response.url, volunteer_index_url) + # social_user = UserSocialAuth.objects.get() + # created_user = social_user.user + # self.assertTrue(created_user.is_staff) + # self.assertTrue(created_user.volunteer_profile) + # self.assertIsNone(created_user.volunteer_profile.area) \ No newline at end of file diff --git a/merepresenta/tests/model_tests.py b/merepresenta/tests/model_tests.py index 2344e101..73726357 100644 --- a/merepresenta/tests/model_tests.py +++ b/merepresenta/tests/model_tests.py @@ -55,9 +55,9 @@ def test_instanciate(self): class CandidateListForVolunteers(TestCase): def test_list_for_volunteers(self): - ghost = Candidate.objects.create(name="Candidate 1", is_ghost=True) - facebook = Candidate.objects.create(name="Candidate 2", facebook_contacted=True) - with_contact = Candidate.objects.create(name="Candidate with Contact") + ghost = Candidate.objects.create(name="Candidate 1", is_ghost=True, cpf='123') + facebook = Candidate.objects.create(name="Candidate 2", facebook_contacted=True, cpf='456') + with_contact = Candidate.objects.create(name="Candidate with Contact", cpf='789') with_contact.contacts.create(mail="perrito@gatito.cl") candidates = Candidate.for_volunteers.all() @@ -69,8 +69,8 @@ def test_list_for_volunteers(self): def test_if_has_a_volunteer_looking_for_more_than_an_hour(self): volunteer = User.objects.create_user(username='volunteer', is_staff=True) always_in_list = Candidate.objects.create(name="Always") - checked_twenty_nine_minutes_ago = Candidate.objects.create(name="Checked 29 minutes ago") - checked_thirty_one_minutes_ago = Candidate.objects.create(name="Checked 31 minutes ago") + checked_twenty_nine_minutes_ago = Candidate.objects.create(name="Checked 29 minutes ago", cpf='29') + checked_thirty_one_minutes_ago = Candidate.objects.create(name="Checked 31 minutes ago", cpf='31') minutes = 30 diff --git a/merepresenta/tse_processor.py b/merepresenta/tse_processor.py index 550c20b8..5f67acac 100644 --- a/merepresenta/tse_processor.py +++ b/merepresenta/tse_processor.py @@ -25,18 +25,31 @@ def process_candidate(self, candidate_dict, election, partido): data_de_nascimento = datetime.strptime(candidate_dict['date_of_birth'], "%d/%m/%Y").date() except: data_de_nascimento = None - candidate, created = Candidate.objects.get_or_create(name=candidate_dict['nome'], - nome_completo=candidate_dict['nome_completo'], - numero=candidate_dict['number'], - cpf=candidate_dict['cpf'], - data_de_nascimento=data_de_nascimento, - race=candidate_dict['race'], - original_email=candidate_dict['mail'], - email_repeated=candidate_dict['email_repeated'], - gender=gender) - election.candidates.add(candidate) + if Candidate.objects.filter(cpf=candidate_dict['cpf']).exists(): + self.output_logger_func("CANDIDATE EXISTENTE DETECTADO CPF:" + candidate_dict['cpf'] + " =====================================>") + return Candidate.objects.get(cpf=candidate_dict['cpf']) + candidate, created = Candidate.objects.get_or_create(name=candidate_dict['nome'], cpf=candidate_dict['cpf']) + candidate.nome_completo = candidate_dict['nome_completo'] + candidate.numero = candidate_dict['number'] + candidate.cpf = candidate_dict['cpf'] + candidate.data_de_nascimento = data_de_nascimento + candidate.race = candidate_dict['race'] + candidate.original_email = candidate_dict['mail'] + candidate.email_repeated = candidate_dict['email_repeated'] candidate.partido = partido + candidate.gender = gender candidate.save() + # candidate, created = Candidate.objects.get_or_create(name=candidate_dict['nome'], + # nome_completo=candidate_dict['nome_completo'], + # numero=candidate_dict['number'], + # cpf=candidate_dict['cpf'], + # data_de_nascimento=data_de_nascimento, + # race=candidate_dict['race'], + # original_email=candidate_dict['mail'], + # email_repeated=candidate_dict['email_repeated'], + # partido = partido, + # gender=gender) + election.candidates.add(candidate) return candidate diff --git a/merepresenta/urls.py b/merepresenta/urls.py index 49b2afa1..9591f64b 100644 --- a/merepresenta/urls.py +++ b/merepresenta/urls.py @@ -38,7 +38,7 @@ def get_form_class(self): url(r'^answers/?$', MeRepresentaMeiaLaranjaQuestionsWizardForm.as_view(), name='questions'), - url(r'^candidatos/', include('merepresenta.candidates_backend.urls')), + url(r'^candidatos/', include('merepresenta.candidatos.urls')), url(r'^eleccion/(?P[-\w]+)/(?P[-\w]+)/?$', CandidateDetailView.as_view(template_name='merepresenta/candidate_detail.html'), name='candidate_detail_view'