Create view and model for duplicate member conflicts

This commit is contained in:
Jan Tuomi
2017-05-28 23:40:47 +03:00
parent cc9768b895
commit 09e8c93e8d
7 changed files with 105 additions and 6 deletions
+2 -1
View File
@@ -1,7 +1,8 @@
from django.contrib import admin from django.contrib import admin
from members.models import Member, Request, Payment from members.models import Member, Request, Payment, MemberConflict
# Register your models here. # Register your models here.
admin.site.register(Member) admin.site.register(Member)
admin.site.register(Request) admin.site.register(Request)
admin.site.register(Payment) admin.site.register(Payment)
admin.site.register(MemberConflict)
+24
View File
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-05-28 20:32
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('members', '0011_auto_20170526_2013'),
]
operations = [
migrations.CreateModel(
name='MemberConflict',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('first_member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberconflict_first_member', to='members.Member')),
('second_member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberconflict_second_member', to='members.Member')),
],
),
]
+18
View File
@@ -119,3 +119,21 @@ class Member(BaseMember):
AYY=bool(array[4]), AYY=bool(array[4]),
jas=bool(array[5]), jas=bool(array[5]),
) )
class MemberConflict(models.Model):
first_member = models.ForeignKey('Member', related_name='%(class)s_first_member')
second_member = models.ForeignKey('Member', related_name='%(class)s_second_member')
@property
def first_member_form(self):
return MemberForm(instance=self.first_member)
@property
def second_member_form(self):
return MemberForm(instance=self.second_member)
# To avoid problems with a cyclical import, this is at the bottom of the file
from members.forms import MemberForm # nopep8
+4
View File
@@ -246,3 +246,7 @@ input {
max-width: 100%; max-width: 100%;
height: 10rem !important; height: 10rem !important;
} }
.conflict-row {
overflow: auto;
}
+40
View File
@@ -0,0 +1,40 @@
{% extends "members_base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block content %}
<div>
<div>
<h3>{% trans "Conflicting member entries" %}</h3>
</div>
<div>
<p>{% blocktrans %}Found conflicting member entries. Choose how to handle the problematic data.{% endblocktrans %}</p>
{% for conflict in conflicts %}
<div class="conflict-row bg-info">
<div class="col-md-6">
<table class="table readonly" >
{{ conflict.first_member_form }}
</table>
</div>
<div class="col-md-6">
<table class="table readonly" >
{{ conflict.second_member_form }}
</table>
</div>
<div>
<form action="/members/resolve_conflict" method="POST">{% csrf_token %}
<p>{% blocktrans %}Which one has the correct information for this member?{% endblocktrans %}</p>
<input type="hidden" name="id" value="{{ conflict.id }}">
<button type="submit" name="action" value="first" class="btn btn-primary">{% trans "Accept first and remove second" %}</button>
<button type="submit" name="action" value="second" class="btn btn-primary">{% trans "Accept second and remove first" %}</button>
<button type="submit" name="action" value="both" class="btn btn-primary">{% trans "Accept both as two members" %}</button>
</form>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
+3 -4
View File
@@ -16,6 +16,7 @@ from members.views import member_update
from members.views import member_delete_confirm from members.views import member_delete_confirm
from members.views import member_delete from members.views import member_delete
from members.views import payment_list from members.views import payment_list
from members.views import member_duplicates
# rest api # rest api
from members.views import MemberDetail from members.views import MemberDetail
@@ -102,9 +103,7 @@ urlpatterns = [
# rest api url # rest api url
url(r'^api/members/(?P<pk>\d+)$', MemberDetail.as_view()), url(r'^api/members/(?P<pk>\d+)$', MemberDetail.as_view()),
# email validation # member duplicate resolution view
# url(r'^validate/(?P<uidb64>[0-9A-Za-z_\-\']+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', validateEmail, name='user-activation-link'), url(r'^duplicates$', member_duplicates)
# url(r'^validate/success/$', validate_success),
# url(r'^validate/failure/$', validate_fail),
] ]
+14 -1
View File
@@ -26,7 +26,7 @@ import logging
import html import html
import csv import csv
from members.models import Member, Request, Payment from members.models import Member, Request, Payment, MemberConflict
from members.forms import MemberForm, PaymentForm, ApplicationForm from members.forms import MemberForm, PaymentForm, ApplicationForm
# Logger function, you can use the same idea when implementing other loggers to other apps # Logger function, you can use the same idea when implementing other loggers to other apps
@@ -455,6 +455,19 @@ def export_csv(request, *args, **kwargs):
return response return response
@ensure_csrf_cookie
@require_http_methods(["GET"])
@permission_required('members.change_member', login_url='/login')
def member_duplicates(request, *args, **kwargs):
# TODO
conflicts = MemberConflict.objects.all()
context = {
'conflicts': conflicts
}
return render(request, 'member_duplicates.html', context)
def send_mail_wrapper(subject, message, email_to): def send_mail_wrapper(subject, message, email_to):
send_mail(subject, send_mail(subject,
message, message,