admin.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. from django.forms import ModelChoiceField
  6. import autocomplete_light
  7. from .models import ItemType, Item, Loan, Storage
  8. import coin.members.admin
  9. User = get_user_model()
  10. admin.site.register(ItemType)
  11. class OwnerFilter(admin.SimpleListFilter):
  12. title = "Propriétaire"
  13. parameter_name = "owner"
  14. def lookups(self, request, model_admin):
  15. owners = [(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. @admin.register(Item)
  41. class ItemAdmin(admin.ModelAdmin):
  42. list_display = (
  43. "designation",
  44. "mac_address",
  45. "serial",
  46. "owner",
  47. "buy_date",
  48. "deployed",
  49. "is_available",
  50. "storage"
  51. )
  52. list_filter = (
  53. AvailabilityFilter, "type", "storage", "buy_date", OwnerFilter
  54. )
  55. search_fields = (
  56. "designation",
  57. "mac_address",
  58. "serial",
  59. "owner__email",
  60. "owner__nickname",
  61. "owner__first_name",
  62. "owner__last_name",
  63. )
  64. save_as = True
  65. actions = ["give_back"]
  66. form = autocomplete_light.modelform_factory(Loan, fields="__all__")
  67. def give_back(self, request, queryset):
  68. for item in queryset.filter(loans__loan_date_end=None):
  69. item.give_back()
  70. give_back.short_description = "Rendre le matériel"
  71. class StatusFilter(admin.SimpleListFilter):
  72. title = "Statut"
  73. parameter_name = "status"
  74. def lookups(self, request, model_admin):
  75. return [("all", "Tout"), (None, "En cours"), ("finished", "Passés")]
  76. def choices(self, cl):
  77. for lookup, title in self.lookup_choices:
  78. yield {
  79. "selected": self.value() == lookup,
  80. "query_string": cl.get_query_string({self.parameter_name: lookup}, []),
  81. "display": title,
  82. }
  83. def queryset(self, request, queryset):
  84. v = self.value()
  85. if v in (None, "running"):
  86. return queryset.running()
  87. elif v == "finished":
  88. return queryset.finished()
  89. else:
  90. return queryset
  91. class BorrowerFilter(admin.SimpleListFilter):
  92. title = "Adhérent emprunteur"
  93. parameter_name = "user"
  94. def lookups(self, request, model_admin):
  95. users = set()
  96. for loan in model_admin.get_queryset(request):
  97. users.add((loan.user.pk, loan.user))
  98. return users
  99. def queryset(self, request, queryset):
  100. if self.value():
  101. return queryset.filter(user=self.value())
  102. else:
  103. return queryset
  104. class ItemChoiceField(ModelChoiceField):
  105. # On surcharge cette méthode pour afficher mac et n° de série dans le menu
  106. # déroulant de sélection d'un objet dans la création d'un prêt.
  107. def label_from_instance(self, obj):
  108. return obj.designation + " " + obj.get_mac_and_serial()
  109. @admin.register(Loan)
  110. class LoanAdmin(admin.ModelAdmin):
  111. list_display = ("item", "get_mac_and_serial", "user", "loan_date", "loan_date_end")
  112. list_filter = (StatusFilter, BorrowerFilter, "item__designation")
  113. search_fields = (
  114. "item__designation",
  115. "user__nickname",
  116. "user__username",
  117. "user__first_name",
  118. "user__last_name",
  119. )
  120. actions = ["end_loan"]
  121. def end_loan(self, request, queryset):
  122. queryset.filter(loan_date_end=None).update(loan_date_end=datetime.now())
  123. end_loan.short_description = "Mettre fin au prêt"
  124. form = autocomplete_light.modelform_factory(Loan, fields="__all__")
  125. def formfield_for_foreignkey(self, db_field, request, **kwargs):
  126. if db_field.name == "item":
  127. kwargs["queryset"] = Item.objects.all()
  128. return ItemChoiceField(**kwargs)
  129. else:
  130. return super(LoanAdmin, self).formfield_for_foreignkey(
  131. db_field, request, **kwargs
  132. )
  133. @admin.register(Storage)
  134. class StorageAdmin(admin.ModelAdmin):
  135. list_display = ("name", "truncated_notes", "items_count")
  136. def truncated_notes(self, obj):
  137. if len(obj.notes) > 50:
  138. return "{}…".format(obj.notes[:50])
  139. else:
  140. return obj.notes
  141. truncated_notes.short_description = "notes"
  142. class LoanInline(admin.TabularInline):
  143. model = Loan
  144. extra = 0
  145. exclude = ("notes",)
  146. readonly_fields = (
  147. "item",
  148. "get_mac_and_serial",
  149. "loan_date",
  150. "loan_date_end",
  151. "is_running",
  152. )
  153. show_change_link = True
  154. def get_queryset(self, request):
  155. qs = super(LoanInline, self).get_queryset(request)
  156. return qs.order_by("-loan_date_end")
  157. def has_add_permission(self, request, obj=None):
  158. return False
  159. def has_delete_permission(self, request, obj=None):
  160. return False
  161. class MemberAdmin(coin.members.admin.MemberAdmin):
  162. inlines = coin.members.admin.MemberAdmin.inlines + [LoanInline]
  163. admin.site.unregister(coin.members.admin.Member)
  164. admin.site.register(coin.members.admin.Member, MemberAdmin)