Create view and model for duplicate member conflicts
This commit is contained in:
+2
-1
@@ -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)
|
||||||
|
|||||||
@@ -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')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -246,3 +246,7 @@ input {
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: 10rem !important;
|
height: 10rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.conflict-row {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user