diff --git a/core/migrations/0004_user_godfathers.py b/core/migrations/0004_user_godfathers.py
new file mode 100644
index 00000000..3bb1f8e6
--- /dev/null
+++ b/core/migrations/0004_user_godfathers.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+from django.conf import settings
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('core', '0003_auto_20160902_1914'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='user',
+ name='godfathers',
+ field=models.ManyToManyField(to=settings.AUTH_USER_MODEL, related_name='godchildren', blank=True),
+ ),
+ ]
diff --git a/core/models.py b/core/models.py
index 5e2479fe..136469df 100644
--- a/core/models.py
+++ b/core/models.py
@@ -168,6 +168,7 @@ class User(AbstractBaseUser):
address = models.CharField(_("address"), max_length=128, blank=True, default="")
parent_address = models.CharField(_("parent address"), max_length=128, blank=True, default="")
is_subscriber_viewable = models.BooleanField(_("is subscriber viewable"), default=True)
+ godfathers = models.ManyToManyField('User', related_name='godchildren', blank=True)
objects = UserManager()
diff --git a/core/templates/core/user_godfathers.jinja b/core/templates/core/user_godfathers.jinja
new file mode 100644
index 00000000..0a5e195d
--- /dev/null
+++ b/core/templates/core/user_godfathers.jinja
@@ -0,0 +1,29 @@
+{% extends "core/base.jinja" %}
+{% from "core/macros.jinja" import user_link_with_pict %}
+
+{% block title %}
+{% trans user_name=profile.get_display_name() %}{{ user_name }}'s godfathers{% endtrans %}
+{% endblock %}
+
+{% block content %}
+
{% trans %}Godfathers{% endtrans %}
+
+ {% for u in profile.godfathers.all() %}
+ - {{ user_link_with_pict(u) }}
+ {% endfor %}
+
+ {% trans %}Godchildren{% endtrans %}
+
+ {% for u in profile.godchildren.all() %}
+ - {{ user_link_with_pict(u) }}
+ {% endfor %}
+
+ {% if profile == user %}
+
+ {% endif %}
+{% endblock %}
+
diff --git a/core/urls.py b/core/urls.py
index 94767c20..f1435b98 100644
--- a/core/urls.py
+++ b/core/urls.py
@@ -32,6 +32,7 @@ urlpatterns = [
url(r'^user/$', UserListView.as_view(), name='user_list'),
url(r'^user/(?P[0-9]+)/mini$', UserMiniView.as_view(), name='user_profile_mini'),
url(r'^user/(?P[0-9]+)/$', UserView.as_view(), name='user_profile'),
+ url(r'^user/(?P[0-9]+)/godfathers$', UserGodfathersView.as_view(), name='user_godfathers'),
url(r'^user/(?P[0-9]+)/edit$', UserUpdateProfileView.as_view(), name='user_edit'),
url(r'^user/(?P[0-9]+)/profile_upload$', UserUploadProfilePictView.as_view(), name='user_profile_upload'),
url(r'^user/(?P[0-9]+)/groups$', UserUpdateGroupView.as_view(), name='user_groups'),
diff --git a/core/views/forms.py b/core/views/forms.py
index 90d6a7de..27226d25 100644
--- a/core/views/forms.py
+++ b/core/views/forms.py
@@ -6,6 +6,7 @@ from django.contrib.auth import logout, login, authenticate
from django.forms import CheckboxSelectMultiple, Select, DateInput, TextInput, DateTimeInput
from django.utils.translation import ugettext as _
from phonenumber_field.widgets import PhoneNumberInternationalFallbackWidget
+from ajax_select.fields import AutoCompleteSelectField
import logging
import re
@@ -198,6 +199,10 @@ class UserPropForm(forms.ModelForm):
'groups': CheckboxSelectMultiple,
}
+class UserGodfathersForm(forms.Form):
+ type = forms.ChoiceField(choices=[('godfather', _("Godfather")), ('godchild', _("Godchild"))], label=_("Add"))
+ user = AutoCompleteSelectField('users', required=True, label=_("Select user"), help_text=None)
+
class PagePropForm(forms.ModelForm):
error_css_class = 'error'
required_css_class = 'required'
diff --git a/core/views/user.py b/core/views/user.py
index bead071f..71e0b7fc 100644
--- a/core/views/user.py
+++ b/core/views/user.py
@@ -18,7 +18,7 @@ from datetime import timedelta, datetime, date
import logging
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin
-from core.views.forms import RegisteringForm, UserPropForm, UserProfileForm, LoginForm
+from core.views.forms import RegisteringForm, UserPropForm, UserProfileForm, LoginForm, UserGodfathersForm
from core.models import User, SithFile
from subscription.models import Subscription
@@ -128,6 +128,11 @@ class UserTabsMixin(TabedViewMixin):
'slug': 'infos',
'name': _("Infos"),
})
+ tab_list.append({
+ 'url': reverse('core:user_godfathers', kwargs={'user_id': self.object.id}),
+ 'slug': 'godfather',
+ 'name': _("Godfathers"),
+ })
if self.request.user == self.object:
tab_list.append({
'url': reverse('core:user_tools'),
@@ -174,6 +179,37 @@ class UserView(UserTabsMixin, CanViewMixin, DetailView):
template_name = "core/user_detail.jinja"
current_tab = 'infos'
+class UserGodfathersView(UserTabsMixin, CanViewMixin, DetailView):
+ """
+ Display a user's godfathers
+ """
+ model = User
+ pk_url_kwarg = "user_id"
+ context_object_name = "profile"
+ template_name = "core/user_godfathers.jinja"
+ current_tab = 'godfathers'
+
+ def post(self, request, *args, **kwargs):
+ self.object = self.get_object()
+ self.form = UserGodfathersForm(request.POST)
+ if self.form.is_valid() and self.form.cleaned_data['user'] != self.object:
+ if self.form.cleaned_data['type'] == 'godfather':
+ self.object.godfathers.add(self.form.cleaned_data['user'])
+ self.object.save()
+ else:
+ self.object.godchildren.add(self.form.cleaned_data['user'])
+ self.object.save()
+ self.form = UserGodfathersForm()
+ return super(UserGodfathersView, self).get(request, *args, **kwargs)
+
+ def get_context_data(self, **kwargs):
+ kwargs = super(UserGodfathersView, self).get_context_data(**kwargs)
+ try:
+ kwargs['form'] = self.form
+ except:
+ kwargs['form'] = UserGodfathersForm()
+ return kwargs
+
class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
"""
Display a user's stats
diff --git a/migrate.py b/migrate.py
index b22d902d..90dfcded 100644
--- a/migrate.py
+++ b/migrate.py
@@ -944,6 +944,24 @@ def migrate_accounting():
migrate_operations()
make_operation_links()
+def migrate_godfathers():
+ cur = db.cursor(MySQLdb.cursors.SSDictCursor)
+ cur.execute("""
+ SELECT *
+ FROM parrains
+ """)
+ for r in cur:
+ try:
+ father = User.objects.filter(id=r['id_utilisateur']).first()
+ child = User.objects.filter(id=r['id_utilisateur_fillot']).first()
+ father.godchildren.add(child)
+ father.save()
+ except Exception as e:
+ print("FAIL to migrate godfathering: %s" % (repr(e)))
+ cur.close()
+ print("Godfathers migrated at %s" % datetime.datetime.now())
+ print("Running time: %s" % (datetime.datetime.now()-start))
+
def main():
print("Start at %s" % start)
# Core
@@ -957,8 +975,9 @@ def main():
# check_accounts()
# Accounting
# migrate_accounting()
- reset_index('core', 'club', 'subscription', 'accounting', 'eboutic', 'launderette', 'counter')
- # end = datetime.datetime.now()
+ migrate_godfathers()
+ # reset_index('core', 'club', 'subscription', 'accounting', 'eboutic', 'launderette', 'counter')
+ end = datetime.datetime.now()
print("End at %s" % end)
print("Running time: %s" % (end-start))