admin.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. from django.contrib import admin
  2. from django.contrib.contenttypes.admin import GenericStackedInline, GenericTabularInline
  3. from django.db.models import Q
  4. from django.contrib.contenttypes.models import ContentType
  5. from django.contrib.auth.models import User as AuthUser
  6. from django.contrib.auth.admin import UserAdmin as AuthUserAdmin
  7. from django.http import HttpResponseRedirect
  8. from django.utils.html import format_html, mark_safe
  9. from django.urls import reverse
  10. from django.utils import timezone
  11. from .forms import UserCreationForm
  12. from .models import User, Corporation, Adhesion
  13. from accounts.models import Profile
  14. from services.models import Service
  15. from djadhere.utils import ActiveFilter, get_active_filter
  16. from banking.models import PaymentUpdate
  17. from datetime import timedelta
  18. ### Inlines
  19. class ProfileInline(admin.StackedInline):
  20. model = Profile
  21. def has_add_permission(self, request):
  22. return False
  23. def has_delete_permission(self, request, obj=None):
  24. return False
  25. class AdhesionInline(admin.StackedInline):
  26. model = Adhesion
  27. fields = ('id', 'notes',)
  28. def has_add_permission(self, request):
  29. return False
  30. def has_delete_permission(self, request, obj=None):
  31. return False
  32. class ServiceInline(admin.StackedInline):
  33. model = Service
  34. extra = 0
  35. show_change_link = True
  36. fields = ('service_type', 'label',)
  37. readonly_fields = ('service_type', 'label',)
  38. def has_add_permission(self, request):
  39. return False
  40. def has_delete_permission(self, request, obj=None):
  41. return False
  42. class ActiveServiceInline(ServiceInline):
  43. verbose_name_plural = 'Services actifs'
  44. def get_queryset(self, request):
  45. return super().get_queryset(request).filter(get_active_filter('allocation'))
  46. class InactiveServiceInline(ServiceInline):
  47. verbose_name_plural = 'Anciens services'
  48. def get_queryset(self, request):
  49. return super().get_queryset(request).exclude(get_active_filter('allocation'))
  50. ### Filters
  51. class AdherentTypeFilter(admin.SimpleListFilter):
  52. title = 'type d’adhérent'
  53. parameter_name = 'type'
  54. def lookups(self, request, model_admin):
  55. return (
  56. ('physique', 'Personne physique'),
  57. ('morale', 'Personne morale'),
  58. )
  59. def queryset(self, request, queryset):
  60. if self.value() == 'physique':
  61. return queryset.filter(user__isnull=False)
  62. if self.value() == 'morale':
  63. return queryset.filter(corporation__isnull=False)
  64. ### Mixins
  65. class AdtSearchMixin:
  66. adhesion_search_field = 'id'
  67. def get_search_results(self, request, queryset, search_term):
  68. queryset, use_distinct = super().get_search_results(request, queryset, search_term)
  69. if search_term[:3] == 'ADT':
  70. try:
  71. adh_id = int(search_term[3:])
  72. except ValueError:
  73. pass
  74. else:
  75. queryset |= self.model.objects.filter(**{self.adhesion_search_field: adh_id})
  76. return queryset, use_distinct
  77. ### ModelAdmin
  78. class UserAdmin(AdtSearchMixin, AuthUserAdmin):
  79. list_display = AuthUserAdmin.list_display + ('get_adhesion_link',)
  80. list_select_related = ('profile', 'adhesion',)
  81. ordering = ('adhesion__id',)
  82. search_fields = AuthUserAdmin.search_fields \
  83. + ('profile__phone_number', 'profile__address', 'profile__notes',) \
  84. + ('=adhesion__id', 'adhesion__notes',)
  85. readonly_fields = ('get_adhesion_link',)
  86. adhesion_search_field = 'adhesion__id'
  87. def get_adhesion_id(self, user):
  88. return user.adhesion
  89. get_adhesion_id.short_description = 'Numéro d’adhérent'
  90. get_adhesion_id.admin_order_field = 'adhesion__id'
  91. get_adhesion_link = lambda self, corporation: corporation.adhesion.get_adhesion_link()
  92. get_adhesion_link.short_description = Adhesion.get_adhesion_link.short_description
  93. def get_inline_instances(self, request, obj=None):
  94. if obj:
  95. inlines = (ProfileInline, AdhesionInline,)
  96. else:
  97. inlines = ()
  98. return [inline(self.model, self.admin_site) for inline in inlines]
  99. def get_form(self, request, obj=None, **kwargs):
  100. if obj:
  101. return super().get_form(request, obj, **kwargs)
  102. else:
  103. return UserCreationForm
  104. def get_fieldsets(self, request, obj=None):
  105. if obj:
  106. fieldsets = (
  107. (AuthUserAdmin.fieldsets[1][0], {
  108. 'fields': ('get_adhesion_link',) + AuthUserAdmin.fieldsets[1][1]['fields'],
  109. }),
  110. ('Nom d’utilisateur et mot de passe', {
  111. 'classes': ('collapse',),
  112. 'fields': AuthUserAdmin.fieldsets[0][1]['fields'],
  113. }),
  114. (AuthUserAdmin.fieldsets[2][0], {
  115. 'classes': ('collapse',),
  116. 'fields': ('is_active', 'is_staff', 'is_superuser', 'groups',), # removing user_permissions
  117. }),
  118. (AuthUserAdmin.fieldsets[3][0], {
  119. 'classes': ('collapse',),
  120. 'fields': AuthUserAdmin.fieldsets[3][1]['fields'],
  121. }),
  122. )
  123. else:
  124. fieldsets = (
  125. (None, {
  126. 'fields': ('first_name', 'last_name', 'username', 'email',),
  127. }),
  128. )
  129. return fieldsets
  130. def get_actions(self, request):
  131. actions = super().get_actions(request)
  132. if 'delete_selected' in actions:
  133. del actions['delete_selected']
  134. return actions
  135. def has_delete_permission(self, request, obj=None):
  136. return obj and not obj.adhesion
  137. class CorporationAdmin(AdtSearchMixin, admin.ModelAdmin):
  138. list_display = ('social_reason', 'get_adhesion_link',)
  139. list_select_related = ('adhesion',)
  140. ordering = ('adhesion__id',)
  141. search_fields = ('social_reason', 'description', 'email', 'phone_number', 'address', 'notes', 'adhesion__id', 'adhesion__notes',)
  142. readonly_fields = ('get_adhesion_link',)
  143. filter_horizontal = ('members',)
  144. adhesion_search_field = 'adhesion__id'
  145. def get_adhesion_id(self, corp):
  146. return corp.adhesion
  147. get_adhesion_id.short_description = 'Numéro d’adhérent'
  148. get_adhesion_id.admin_order_field = 'adhesion__id'
  149. get_adhesion_link = lambda self, corporation: corporation.adhesion.get_adhesion_link()
  150. get_adhesion_link.short_description = Adhesion.get_adhesion_link.short_description
  151. def get_inline_instances(self, request, obj=None):
  152. if obj:
  153. inlines = (AdhesionInline,)
  154. else:
  155. inlines = ()
  156. return [inline(self.model, self.admin_site) for inline in inlines]
  157. def get_actions(self, request):
  158. actions = super().get_actions(request)
  159. if 'delete_selected' in actions:
  160. del actions['delete_selected']
  161. return actions
  162. def get_fieldsets(self, request, obj=None):
  163. fieldsets = super().get_fieldsets(request, obj)
  164. # put adhesion id on top
  165. if obj:
  166. fields = fieldsets[0][1]['fields']
  167. fields.remove('get_adhesion_link')
  168. fieldsets = (
  169. (None, {
  170. 'fields': ['get_adhesion_link'] + fields,
  171. }),
  172. )
  173. return fieldsets
  174. def has_delete_permission(self, request, obj=None):
  175. return False
  176. class AdhesionAdmin(AdtSearchMixin, admin.ModelAdmin):
  177. list_display = ('get_id', 'type', 'get_adherent_link', 'is_active')
  178. list_filter = (AdherentTypeFilter, ActiveFilter)
  179. list_select_related = ('user', 'user__profile', 'corporation',)
  180. fields = ('id', 'type', 'get_adherent_link', 'get_membership_link', 'get_antennas_link',)
  181. readonly_fields = ('id', 'type', 'get_adherent_link', 'get_membership_link', 'get_antennas_link',)
  182. search_fields = ('=id', 'notes',) \
  183. + tuple(['user__%s' % f for f in UserAdmin.search_fields if 'adhesion' not in f]) \
  184. + tuple(['corporation__%s' % f for f in CorporationAdmin.search_fields if 'adhesion' not in f])
  185. inlines = (ActiveServiceInline, InactiveServiceInline,)
  186. def get_id(self, obj):
  187. return 'ADT%d' % obj.id
  188. get_id.short_description = 'Numéro d’adhérent'
  189. get_id.admin_order_field = 'id'
  190. def get_membership_link(self, obj):
  191. return format_html(u'<a href="{}">{}</a>', obj.membership.get_absolute_url(), obj.membership.get_current_payment_display())
  192. get_membership_link.short_description = 'Cotisation'
  193. def get_antennas_link(self, obj):
  194. return mark_safe('<br />'.join(map(lambda antenna: antenna.get_absolute_link(), obj.antenna_set.all())))
  195. get_antennas_link.short_description = 'Antennes'
  196. def get_actions(self, request):
  197. actions = super().get_actions(request)
  198. if 'delete_selected' in actions:
  199. del actions['delete_selected']
  200. return actions
  201. def has_add_permission(self, request):
  202. return False
  203. def has_delete_permission(self, request, obj=None):
  204. if not obj:
  205. return False
  206. one_year_ago = timezone.now() - timedelta(days=365)
  207. membership = obj.membership.updates.filter(validated=True).first()
  208. # si l’adhésion n’a pas été résilié il y a plus d’un an
  209. if not membership or membership.payment_method != PaymentUpdate.STOP or membership.start > one_year_ago:
  210. return False
  211. # si l’adhérent est référent pour une antenne
  212. if obj.antenna_set.exists():
  213. return False
  214. # si l’adherent a un service
  215. if obj.services.exists():
  216. return False
  217. return True
  218. admin.site.unregister(AuthUser)
  219. admin.site.register(User, UserAdmin)
  220. admin.site.register(Corporation, CorporationAdmin)
  221. admin.site.register(Adhesion, AdhesionAdmin)