admin.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.shortcuts import render, get_object_or_404
  4. from django.contrib import admin
  5. from django.contrib import messages
  6. from django.contrib.auth.admin import UserAdmin
  7. from django.contrib.auth.models import Group, Permission
  8. from django.contrib.contenttypes.models import ContentType
  9. from django.http import HttpResponseRedirect
  10. from django.conf.urls import url
  11. from django.db.models.query import QuerySet
  12. from django.core.urlresolvers import reverse
  13. from django.utils.html import format_html
  14. from coin.members.models import (
  15. Member, CryptoKey, LdapUser, MembershipFee, Offer, OfferSubscription, RowLevelPermission)
  16. from coin.members.membershipfee_filter import MembershipFeeFilter
  17. from coin.members.forms import AdminMemberChangeForm, MemberCreationForm
  18. from coin.utils import delete_selected
  19. import autocomplete_light
  20. class CryptoKeyInline(admin.StackedInline):
  21. model = CryptoKey
  22. extra = 0
  23. class MembershipFeeInline(admin.TabularInline):
  24. model = MembershipFee
  25. extra = 0
  26. fields = ('start_date', 'end_date', 'amount', 'payment_method',
  27. 'reference', 'payment_date')
  28. class OfferSubscriptionInline(admin.TabularInline):
  29. model = OfferSubscription
  30. extra = 0
  31. writable_fields = ('subscription_date', 'resign_date', 'commitment', 'offer')
  32. all_fields = ('get_subscription_reference',) + writable_fields
  33. def get_fields(self, request, obj=None):
  34. if obj:
  35. return self.all_fields
  36. else:
  37. return self.writable_fields
  38. def get_readonly_fields(self, request, obj=None):
  39. # création ou superuser : lecture écriture
  40. if not obj or request.user.is_superuser:
  41. return ('get_subscription_reference',)
  42. # modification : lecture seule seulement
  43. else:
  44. return self.all_fields
  45. show_change_link = True
  46. def formfield_for_foreignkey(self, db_field, request, **kwargs):
  47. if request.user.is_superuser:
  48. return super(OfferSubscriptionInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
  49. else:
  50. if db_field.name == "offer":
  51. kwargs["queryset"] = Offer.objects.manageable_by(request.user)
  52. return super(OfferSubscriptionInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
  53. # pas très beau
  54. # quand on créer un membre on autorise à ajouter un abonnement
  55. # sinon seulement en lecture seule (sinon ça permettrait de changer les abo qu'on n'a pas le droit de toucher)
  56. def has_add_permission(self, request):
  57. if request.path.split('/')[-2] == 'add':
  58. return True
  59. else:
  60. return request.user.is_superuser
  61. # sinon on pourrait supprimer les abo qu'on ne peut pas gérer
  62. # pourrait peut-être être plus fin, obj réfère ici au member de la page
  63. def has_delete_permission(self, request, obj=None):
  64. return request.user.is_superuser
  65. class MemberAdmin(UserAdmin):
  66. list_display = ('id', 'status', 'username', 'first_name', 'last_name',
  67. 'nickname', 'organization_name', 'email',
  68. 'end_date_of_membership')
  69. list_display_links = ('id', 'username', 'first_name', 'last_name')
  70. list_filter = ('status', MembershipFeeFilter)
  71. search_fields = ['username', 'first_name', 'last_name', 'email', 'nickname']
  72. ordering = ('status', 'username')
  73. actions = [delete_selected, 'set_as_member', 'set_as_non_member',
  74. 'bulk_send_welcome_email', 'bulk_send_call_for_membership_fee_email']
  75. form = AdminMemberChangeForm
  76. add_form = MemberCreationForm
  77. def get_fieldsets(self, request, obj=None):
  78. coord_fieldset = ('Coordonnées', {'fields': (
  79. ('email', 'send_membership_fees_email'),
  80. ('home_phone_number', 'mobile_phone_number'),
  81. 'address',
  82. ('postal_code', 'city', 'country'))})
  83. auth_fieldset = ('Authentification', {'fields': (
  84. ('username', 'password'))})
  85. perm_fieldset = ('Permissions', {'fields': (
  86. ('is_active', 'is_staff', 'is_superuser', 'groups'))})
  87. # if obj is null then it is a creation, otherwise it is a modification
  88. if obj:
  89. return (
  90. ('Adhérent', {'fields': (
  91. ('status', 'date_joined', 'resign_date'),
  92. 'type',
  93. ('first_name', 'last_name', 'nickname'),
  94. 'organization_name',
  95. 'comments',
  96. 'balance' # XXX we shouldn't need this, the default value should be used
  97. )}),
  98. coord_fieldset,
  99. auth_fieldset,
  100. perm_fieldset,
  101. (None, {'fields': ('date_last_call_for_membership_fees_email',)})
  102. )
  103. else:
  104. return (
  105. ('Adhérent', {'fields': (
  106. ('status', 'date_joined'),
  107. 'type',
  108. ('first_name', 'last_name', 'nickname'),
  109. 'organization_name',
  110. 'comments',
  111. 'balance')}),
  112. coord_fieldset,
  113. auth_fieldset,
  114. perm_fieldset
  115. )
  116. radio_fields = {"type": admin.HORIZONTAL}
  117. save_on_top = True
  118. inlines = [CryptoKeyInline, MembershipFeeInline, OfferSubscriptionInline]
  119. def get_queryset(self, request):
  120. qs = super(MemberAdmin, self).get_queryset(request)
  121. if request.user.is_superuser:
  122. return qs
  123. else:
  124. offers = Offer.objects.manageable_by(request.user)
  125. return qs.filter(offersubscription__offer__in=offers).distinct()
  126. def get_readonly_fields(self, request, obj=None):
  127. readonly_fields = []
  128. if obj:
  129. # Remove help_text for readonly field (can't do that in the Form
  130. # django seems to user help_text from model for readonly fields)
  131. username_field = [
  132. f for f in obj._meta.fields if f.name == 'username']
  133. username_field[0].help_text = ''
  134. readonly_fields.append('username')
  135. if not request.user.is_superuser:
  136. readonly_fields += ['is_active', 'is_staff', 'is_superuser', 'groups', 'date_last_call_for_membership_fees_email']
  137. return readonly_fields
  138. def set_as_member(self, request, queryset):
  139. rows_updated = queryset.update(status='member')
  140. self.message_user(
  141. request,
  142. '%d membre(s) définis comme adhérent(s).' % rows_updated)
  143. set_as_member.short_description = 'Définir comme adhérent'
  144. def set_as_non_member(self, request, queryset):
  145. rows_updated = queryset.update(status='not_member')
  146. self.message_user(
  147. request,
  148. '%d membre(s) définis comme non adhérent(s).' % rows_updated)
  149. set_as_non_member.short_description = "Définir comme non adhérent"
  150. def get_urls(self):
  151. """Custom admin urls"""
  152. urls = super(MemberAdmin, self).get_urls()
  153. my_urls = [
  154. url(r'^send_welcome_email/(?P<id>\d+)$',
  155. self.admin_site.admin_view(self.send_welcome_email),
  156. name='send_welcome_email'),
  157. ]
  158. return my_urls + urls
  159. def send_welcome_email(self, request, id, return_httpredirect=True):
  160. """
  161. Vue appelée lorsque l'admin souhaite envoyer l'email de bienvenue à un
  162. membre.
  163. """
  164. # TODO : Add better perm here
  165. if request.user.is_superuser:
  166. member = get_object_or_404(Member, pk=id)
  167. member.send_welcome_email()
  168. messages.success(request,
  169. 'Le courriel de bienvenue a été envoyé à %s' % member.email)
  170. else:
  171. messages.error(
  172. request, 'Vous n\'avez pas l\'autorisation d\'envoyer des '
  173. 'courriels de bienvenue.')
  174. if return_httpredirect:
  175. return HttpResponseRedirect(reverse('admin:members_member_changelist'))
  176. def bulk_send_welcome_email(self, request, queryset):
  177. """
  178. Action appelée lorsque l'admin souhaite envoyer un lot d'email de bienvenue
  179. depuis une sélection de membre dans la vue liste de l'admin
  180. """
  181. for member in queryset.all():
  182. self.send_welcome_email(
  183. request, member.id, return_httpredirect=False)
  184. messages.success(request,
  185. 'Le courriel de bienvenue a été envoyé à %d membre(s).' % queryset.count())
  186. bulk_send_welcome_email.short_description = "Envoyer le courriel de bienvenue"
  187. def bulk_send_call_for_membership_fee_email(self, request, queryset):
  188. # TODO : Add better perm here
  189. if not request.user.is_superuser:
  190. messages.error(
  191. request, 'Vous n\'avez pas l\'autorisation d\'envoyer des '
  192. 'courriels de relance.')
  193. return
  194. cpt_success = 0
  195. for member in queryset.all():
  196. if member.send_call_for_membership_fees_email():
  197. cpt_success += 1
  198. else:
  199. messages.warning(request,
  200. "Le courriel de relance de cotisation n\'a pas "
  201. "été envoyé à {member} ({email}) car il a déjà "
  202. "reçu une relance le {last_call_date}"\
  203. .format(member=member,
  204. email=member.email,
  205. last_call_date=member.date_last_call_for_membership_fees_email))
  206. if queryset.count() == 1 and cpt_success == 1:
  207. member = queryset.first()
  208. messages.success(request,
  209. "Le courriel de relance de cotisation a été "
  210. "envoyé à {member} ({email})"\
  211. .format(member=member, email=member.email))
  212. elif cpt_success>1:
  213. messages.success(request,
  214. "Le courriel de relance de cotisation a été "
  215. "envoyé à {cpt} membres"\
  216. .format(cpt=cpt_success))
  217. bulk_send_call_for_membership_fee_email.short_description = 'Envoyer le courriel de relance de cotisation'
  218. class MembershipFeeAdmin(admin.ModelAdmin):
  219. list_display = ('member', 'end_date', 'amount', 'payment_method',
  220. 'payment_date')
  221. form = autocomplete_light.modelform_factory(MembershipFee, fields='__all__')
  222. class RowLevelPermissionAdmin(admin.ModelAdmin):
  223. def get_changeform_initial_data(self, request):
  224. return {'content_type': ContentType.objects.get_for_model(OfferSubscription)}
  225. admin.site.register(Member, MemberAdmin)
  226. admin.site.register(MembershipFee, MembershipFeeAdmin)
  227. # admin.site.unregister(Group)
  228. # admin.site.register(LdapUser, LdapUserAdmin)
  229. admin.site.register(RowLevelPermission, RowLevelPermissionAdmin)