admin.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.contrib import admin
  4. from django.contrib.auth import get_user_model
  5. import autocomplete_light
  6. from .models import ItemType, Item, Loan, Storage
  7. import coin.members.admin
  8. User = get_user_model()
  9. admin.site.register(ItemType)
  10. class OwnerFilter(admin.SimpleListFilter):
  11. title = "Propriétaire"
  12. parameter_name = 'owner'
  13. def lookups(self, request, model_admin):
  14. owners = [
  15. (i.pk, i) for i in User.objects.filter(items__isnull=False)]
  16. return [(None, "L'association")] + owners
  17. def queryset(self, request, queryset):
  18. if self.value():
  19. return queryset.filter(owner__pk=self.value())
  20. else:
  21. return queryset
  22. class AvailabilityFilter(admin.SimpleListFilter):
  23. title = "Disponibilité"
  24. parameter_name = 'availability'
  25. def lookups(self, request, model_admin):
  26. return [
  27. ('available', 'Disponible'),
  28. ('borrowed', 'Emprunté'),
  29. ('deployed', 'Déployé'),
  30. ]
  31. def queryset(self, request, queryset):
  32. if self.value() == 'available':
  33. return queryset.available()
  34. elif self.value() == 'borrowed':
  35. return queryset.borrowed()
  36. elif self.value() == 'deployed':
  37. return queryset.deployed()
  38. else:
  39. return queryset
  40. class CurrentLoanInline(admin.TabularInline):
  41. model = Loan
  42. extra = 0
  43. fields = ('user', 'item', 'short_date', 'notes')
  44. readonly_fields = ('user', 'item', 'short_date', 'notes')
  45. verbose_name_plural = "Emprunt en cours"
  46. show_change_link = True
  47. def get_queryset(self, request):
  48. qs = super(CurrentLoanInline, self).get_queryset(request)
  49. return qs.running()
  50. def has_add_permission(self, request, obj=None):
  51. return False
  52. def has_delete_permission(self, request, obj=None):
  53. return False
  54. class LoanHistoryInline(admin.TabularInline):
  55. model = Loan
  56. extra = 0
  57. fields = ('user', 'item', 'short_date', 'short_date_end', 'notes')
  58. readonly_fields = ('user', 'item', 'short_date', 'short_date_end', 'notes')
  59. ordering = ['-loan_date_end']
  60. verbose_name_plural = "Historique de prêt de cet objet"
  61. show_change_link = True
  62. classes = ['collapse'] # Django >= 1.10-ready
  63. def get_queryset(self, request):
  64. qs = super(LoanHistoryInline, self).get_queryset(request)
  65. return qs.finished()
  66. def has_add_permission(self, request, obj=None):
  67. return False
  68. def has_delete_permission(self, request, obj=None):
  69. return False
  70. class AddLoanInline(admin.StackedInline):
  71. model = Loan
  72. extra = 1
  73. max_num = 1
  74. fields = ('user', 'item', 'loan_date', 'notes')
  75. verbose_name_plural = "Déclarer le prêt de cet objet"
  76. classes = ['collapse'] # Django >= 1.10-ready
  77. form = autocomplete_light.modelform_factory(Loan, fields='__all__')
  78. def get_queryset(self, request):
  79. qs = super(AddLoanInline, self).get_queryset(request)
  80. return qs.none()
  81. def has_delete_permission(self, request, obj=None):
  82. return False
  83. class BorrowerFilter(admin.SimpleListFilter):
  84. title = 'Adhérent emprunteur'
  85. parameter_name = 'user'
  86. def _filter_loans(self, items_queryset, user_pk=None):
  87. qs = Loan.objects.running().filter(item__in=items_queryset)
  88. if user_pk is not None:
  89. qs.filter(user=user_pk)
  90. return qs
  91. def lookups(self, request, model_admin):
  92. # Get relevant (and authorized) users only
  93. relevant_items = model_admin.get_queryset(request)
  94. users = set()
  95. for loan in self._filter_loans(relevant_items):
  96. users.add((loan.user.pk, loan.user))
  97. return users
  98. def queryset(self, request, queryset):
  99. if self.value():
  100. loans_qs = self._filter_loans(queryset).filter(
  101. user__pk=self.value(),
  102. )
  103. return queryset.filter(loans__in=loans_qs)
  104. else:
  105. return queryset
  106. @admin.register(Item)
  107. class ItemAdmin(admin.ModelAdmin):
  108. list_display = (
  109. 'designation',
  110. 'current_borrower',
  111. 'get_mac_and_serial',
  112. 'deployed', 'is_available', 'storage',
  113. 'buy_date', 'owner',
  114. )
  115. list_filter = (
  116. AvailabilityFilter, 'type', 'storage',
  117. 'buy_date', BorrowerFilter, OwnerFilter)
  118. search_fields = (
  119. 'designation', 'mac_address', 'serial',
  120. 'owner__email', 'owner__nickname',
  121. 'owner__first_name', 'owner__last_name')
  122. save_as = True
  123. actions = ['give_back']
  124. form = autocomplete_light.modelform_factory(Loan, fields='__all__')
  125. inlines = [AddLoanInline, CurrentLoanInline, LoanHistoryInline]
  126. def give_back(self, request, queryset):
  127. for item in queryset.filter(loans__loan_date_end=None):
  128. item.give_back()
  129. give_back.short_description = 'Rendre le matériel'
  130. class StatusFilter(admin.SimpleListFilter):
  131. title = 'Statut'
  132. parameter_name = 'status'
  133. def lookups(self, request, model_admin):
  134. return [
  135. ('all', 'Tout'),
  136. (None, 'En cours'),
  137. ('finished', 'Passés'),
  138. ]
  139. def choices(self, cl):
  140. for lookup, title in self.lookup_choices:
  141. yield {
  142. 'selected': self.value() == lookup,
  143. 'query_string': cl.get_query_string({
  144. self.parameter_name: lookup,
  145. }, []),
  146. 'display': title,
  147. }
  148. def queryset(self, request, queryset):
  149. v = self.value()
  150. if v in (None, 'running'):
  151. return queryset.running()
  152. elif v == 'finished':
  153. return queryset.finished()
  154. else:
  155. return queryset
  156. @admin.register(Storage)
  157. class StorageAdmin(admin.ModelAdmin):
  158. list_display = ('name', 'truncated_notes', 'items_count')
  159. def truncated_notes(self, obj):
  160. if len(obj.notes) > 50:
  161. return '{}…'.format(obj.notes[:50])
  162. else:
  163. return obj.notes
  164. truncated_notes.short_description = 'notes'
  165. class LoanInline(admin.TabularInline):
  166. model = Loan
  167. extra = 0
  168. exclude = ('notes',)
  169. readonly_fields = ('item', 'get_mac_and_serial', 'loan_date', 'loan_date_end', 'is_running')
  170. show_change_link = True
  171. def get_queryset(self, request):
  172. qs = super(LoanInline, self).get_queryset(request)
  173. return qs.order_by('-loan_date_end')
  174. def has_add_permission(self, request, obj=None):
  175. return False
  176. def has_delete_permission(self, request, obj=None):
  177. return False
  178. class MemberAdmin(coin.members.admin.MemberAdmin):
  179. inlines = coin.members.admin.MemberAdmin.inlines + [LoanInline]
  180. admin.site.unregister(coin.members.admin.Member)
  181. admin.site.register(coin.members.admin.Member, MemberAdmin)